I would need to provide an if or..., else condition inside a dockerfile.
I found a solution for an if, else... But I am not able to include an or condition inside the if
This solution works:
RUN if [ condition 1 ] ; then \
command 1; \
else; then \
condition 2; fi
I have tried something like this, unsuccessfully:
RUN if [ condition 1 | condition 2 ] ; then \
command 1; \
else; then \
condition 2; fi
How can I add the or inside the conditional?
Within a single Docker RUN instruction, you're running a shell command, and any Bourne shell syntax is allowed. If you're using [ ... ] that's actually running test(1) which has a -o operator for "or".
RUN if [ condition1 -o condition 2 ]; then \
command1; \
else \
command2; \
fi
The POSIX spec suggests the -o option is obsolete, and recommends using the shell || operator instead.
RUN if [ condition1 ] || [ condition2 ]; then ...; fi
RUN if test condition1 || test condition2 ; then ...; fi
More generally, Dockerfiles don't support conditionals; you can't conditionally COPY a file in, for example. Conversely, if you are writing complex installation logic, you can write and test an ordinary shell script on the host, COPY it into the image, and RUN it, which can be easier than trying to remember to backslash-escape every line ending.
Related
I need to call submakes recursively with different variable settings. During this, I need to build a list of the variable settings. After all submakes are complete, I need to check the results of all the submakes using the list built up.
tests:
echo "Testcase 1 $(testname)..."; \
$(MAKE) -e TESTCASE=1 guimode=no run > test.tc1.log; \ # must save variable TESTCASE_LIST = {1} or similar
$(MAKE) -e TESTCASE=2 guimode=no run > test.tc2.log; \ # must append to variable TESTCASE_LIST = {1 2}
$(MAKE) -e TESTCASE=2 guimode=no run > test.tc3.log; \ # must append to variable TESTCASE_LIST = {1 2 3}
echo "Completed Tests at time $(realtime) ..."; \
$(MAKE) check_test_results; # must run through results of tests 1,2,3 and get data
check_test_results:
for testcase in $(TESTCASE_LIST); do something; done
Sub-make is a child process, so it cannot transfer environment variables to its parent. I suggest simply to examine exit codes and process them inside tests recipe, kind of:
.ONESHELL:
tests:
$(MAKE) TEST=1 ... && TESTCASE_LIST+=(1)
$(MAKE) TEST=2 ... && TESTCASE_LIST+=(2)
...
# check results
echo "Successful tests: $${TESTCASE_LIST[#]}"
I have branch folder "feature-set" under this folder there's multibranch
I need to run the below script in my Jenkinsfile with a condition if this build runs from any branches under the "feature-set" folder like "feature-set/" then run the script
the script is:
sh """
if [ ${env.BRANCH_NAME} = "feature-set*" ]
then
echo ${env.BRANCH_NAME}
branchName='${env.BRANCH_NAME}' | cut -d'\\/' -f 2
echo \$branchName
npm install
ng build --aot --output-hashing none --sourcemap=false
fi
"""
the current output doesn't get the condition:
[ feature-set/swat5 = feature-set* ]
any help?
I would re-write this to be primarily Jenkins/Groovy syntax and only go to shell when required.
Based on the info you provided I assume your env.BRANCH_NAME always looks like `feature-set/
// Echo first so we can see value if condition fails
echo(env.BRANCH_NAME)
// startsWith better than contains() based on current usecase
if ( (env.BRANCH_NAME).startsWith('feature-set') ) {
// Split branch string into list based on delimiter
List<String> parts = (env.BRANCH_NAME).tokenize('/')
/**
* Grab everything minus the first part
* This handles branches that include additional '/' characters
* e.g. 'feature-set/feat/my-feat'
*/
branchName = parts[1..-1].join('/')
echo(branchName)
sh('npm install && ng build --aot --output-hashing none --sourcemap=false')
}
This seems to be more on shell side. Since you are planning to use shell if condition the below worked for me.
Administrator1#XXXXXXXX:
$ if [[ ${BRANCH_NAME} = feature-set* ]]; then echo "Success"; fi
Success
Remove the quotes and add an additional "[]" at the start and end respectively.
The additional "[]" works as regex
I am on Linux Mint 19. I am entirely new to Makefiles.
Here is the problematic part:
[ $(shell id --user) -eq 0 ] && ( echo && echo "distrib target has to be run as normal user" && echo && exit 1 )
which throws this error:
[ 1000 -eq 0 ] && ( echo && echo "distrib target has to be run as normal user" && echo && exit 1 )
Makefile:25: recipe for target 'distrib' failed
make: *** [distrib] Error 1
On the contrary, using test command directly proves to be working entirely:
if test $(shell id --user) -eq 0; then ( echo && echo "distrib target has to be run as normal user" && echo && exit 1 ) fi
I want to ask why that is, did I break some Makefile rule?
This doesn't have anything to do with makefiles, it has to do with shell scripting and the difference between using && vs. if in terms of the exit code. You are comparing apples and oranges here.
It's not related to test vs [. If you write the version using [ inside an if statement you'll get the same behavior as you do with test, and if you write the test version with the && model you'll get the same behavior as you do with [.
Run this in your shell:
[ 1000 -eq 0 ] && echo hi
echo $?
Now run this in your shell:
if [ 1000 -eq 0 ]; then echo hi; fi
echo $?
You'll see the former gives a non-0 exit code, while the latter gives a 0 (success) exit code. That's how if works; it "swallows" the exit code of the condition.
Make always looks at the exit code of the shell script to decide if it failed or not.
Generally in make scripting you want to re-arrange your expressions to use || rather than &&. That ensures that if the script exits early it exits with a success code not a failure code. You can write your script like this:
[ $$(id -u) -ne 0 ] || ( echo && echo "distrib target has to be run as normal user" && echo && exit 1 )
Note I use $$(id -u) not $(shell id --user); the recipe is run in the shell already and it's an anti-pattern to use the make shell function in a recipe. Also, the -u option is a POSIX standard option while --user is only available in the GNU utilities version of id.
There are few problems that need to solve.
first there is an error. -bash: /Users/jay/.bash_profile: line 7: `fi'
second, i am having trouble updating .bash_profile to install opencv.
http://www.pyimagesearch.com/2015/06/15/install-opencv-3-0-and-python-2-7-on-osx/
Here are the code below and please help.
many thanks!
# added by Anaconda2 4.2.0 installer
export PATH="/Users/jay/anaconda2/bin:$PATH"
export PATH=/usr/local/bin:$PATH
source '/Users/jay/Downloads/google-cloud-sdk/path.bash.inc'
fi
source '/Users/jay/Downloads/google-cloud-sdk/completion.bash.inc'
fi
# The next line updates PATH for the Google Cloud SDK.
if [ -f /Users/jay/Downloads/google-cloud-sdk/path.bash.inc ]; then
source '/Users/jay/Downloads/google-cloud-sdk/path.bash.inc'
fi
# The next line enables shell command completion for gcloud.
if [ -f /Users/jay/Downloads/google-cloud-sdk/completion.bash.inc ]; then
source '/Users/jay/Downloads/google-cloud-sdk/completion.bash.inc'
you have fi statements without if (fi is the 'closing' statement for an 'opening' if):
source '/Users/jay/Downloads/google-cloud-sdk/path.bash.inc'
fi
source '/Users/jay/Downloads/google-cloud-sdk/completion.bash.inc'
fi
bash syntax for if statements is e.g.
if [ -f /var/log/messages ]; then
echo "/var/log/messages exists."
fi
so for you this may be:
if [ -f '/Users/jay/Downloads/google-cloud-sdk/path.bash.inc']; then
source '/Users/jay/Downloads/google-cloud-sdk/path.bash.inc'
fi
and similar for the next line.
and there is a final fi missing at the end of your file.
a simple question:
I want to move emails with a certain subject to a folder and mark them as read afterwards. Moving works for me with
:0: H
* ^Subject:.*(ThisIsMySubject)
$HOME/mail/ThisIsMyFolder
But how to mark the mails as read?
Note: Updated dec. 16th 2011
Procmail solution
The following recipe works for me. .Junk is the spam folder:
MAILDIR=$HOME/Maildir
:0
* ^X-Spam-Flag: YES
{
# First deliver to maildir so LASTFOLDER gets set
:0 c
.Junk
# Manipulate the filename
:0 ai
* LASTFOLDER ?? ()\/[^/]+^^
|mv "$LASTFOLDER" "$MAILDIR/.Junk/cur/$MATCH:2,S"
}
Maildrop solution
Preface: Recently I had (no, I wanted) to do the same thing with a maildropfilter. After reading man maildropfilter I concocted the following recipe. I'm sure people will find this handy - I know I do.
The example below marks new emails as read but also unread old messages.
SPAMDIRFULL="$DEFAULT/.Junk"
if ( /^X-Spam-Flag: YES$/ || \
/^X-Spam-Level: \*\*\*/ || \
/^Subject: \*+SPAM\*/ )
{
exception {
cc "$SPAMDIRFULL"
`for x in ${SPAMDIRFULL}/new/*; do [ -f $x ] && mv $x ${SPAMDIRFULL}/cur/${x##*/}:2,S; done`
`for x in ${SPAMDIRFULL}/cur/*:2,; do [ -f $x ] && mv $x ${SPAMDIRFULL}/cur/${x##*/}S; done`
to "/dev/null"
}
}
Note that the exception command might read counterintuitive. The manual states the following:
The exception statement traps errors that would normally cause
maildrop to terminate. If a fatal error is encountered anywhere within
the block of statements enclosed by the exception clause, execution
will resume immediately following the exception clause.