It never ceases to amaze me how people refuse to make use of the exit code of 
unix commands to write readable shell scripts.

So, instead of writing

> make my_target
> if [[ $? -ne 0 ]]; then
>   ret=1
>   echo "Make has failed" >&2
> fi

You could make it simpler:

if ! make my_target; then
    echo "Make has failed" >&2
fi

I usually keep the if command simple and write that as:

if make my_target; then
    :
else
    echo "Make has failed" >&2
fi

However, I do not usually go for such structures in Jenkins scripts. Jenkins 
runs the scripts with "/bin/sh -xe", which is a good choice: You see the steps 
executed and the first step that fails, aborts the script. Just like when you 
use make and Makefile, usually you want all the steps in your build step to 
succeed, or at least I do.

The few places that I do not care, I either wrap into set +e/set -e or append " 
|| true", if it was just a single command.

If you use the scripts also interactively, it is good to have code to clean up 
background processes. If the scripts are for Jenkins, you do not need to care. 
Jenkins will find the background processes and kill them.

-- Sami

bl0ck3r <[email protected]> kirjoitti 31.3.2013 kello 5.42:

> Bash is very good when the problem is solved by running unix commands. 
> Learning bash is key, and I strongly recommend the O'Reilly book "Learning 
> the bash shell". The bash shell is mature and even if the book does not cover 
> bash 4, all the fundamentals are there. I can recommend three sites for bash:
> http://mywiki.wooledge.org/EnglishFrontPage
> http://wiki.bash-hackers.org/doku.php
> http://tldp.org/LDP/abs/html/
> 
> Exit codes are easy to master. An exit code of zero means the command has 
> "passed", anything else means the command has failed somehow. For example:
> make my_target
> if [[ $? -ne 0 ]]; then
>   ret=1
>   echo "Make has failed" >&2
> fi
> 
> I keep all my problems in the pass/fail category, and I never try to 
> interpret non-zero exit codes because it gets too complicated. However it is 
> key that any script underneath returns an exit code to its caller, all the 
> way up to Jenkins, so make sure your Jenkins build step has an exit statement 
> with an exit code that represents the "worst" error reported underneath.
> 
> If you use pipes, you should always use "set -o pipefail". This will make 
> sure that the pipe will not hide a failure (see man bash):
> $ (exit 1 | echo "hi")
> hi
> $ echo $?
> 0
> $ set -o pipefail
> $ (exit 1 | echo "hi")
> hi
> $ echo $?
> 1
> 
> Now regarding Jenkins, when you have a parametrized build, Jenkins exports 
> those parameters as shell variables that match your parameter names. You can 
> see them in the console by adding the "env" command to your free style build. 
> Also I recommend you always use the shebang to start your free style build 
> (Jenkins will run your script with the -e option, but there are too many 
> exceptions to "set -e", so I just use #!/bin/bash, see: 
> http://mywiki.wooledge.org/BashFAQ/105)
> 
> If you background jobs, you will need to keep track of their process ids, for 
> example set a trap:
> function onKill {
>   kill $pid
>   ... other clean up you might want to do goes here
> }
> ./my_script & pid=$!
> trap 'onKill; exit 1;' SIGINT SIGTERM
> wait $pid
> if [[ $? -ne 0 ]];
>   echo "my_script failed" &2
> fi
> 
> You will also need to generate JUnit XML reports in the format that Jenkins 
> understand. Java is not the language of my builds, and it was very painful to 
> figure out what Jenkins supported. It was a lot of trial an error, and there 
> are many unclear explanations on the internet. I ended up with something 
> similar to this: 
> http://pzolee.blogs.balabit.com/2012/11/jenkins-vs-junit-xml-format/
> 
> My bash build step does not generate XML reports, but commands inside GNU 
> Make, which is called by my script, do (it is actually many layers below the 
> Jenkins "script window" in my case).
> 
> Last advice, keep the code in the build phase window to the bare minimum: put 
> all the smarts in a script that Jenkins calls instead. This way you don't 
> have to copy and paste bug fixes when you have the same script in multiple 
> builds: you simply fix the script that Jenkins calls.
> 
> Bash is very powerful if you learn it well. If you need to manipulate data 
> structures, then you will need to move up to a higher level language like 
> python, but if all your build does is call commands and watch exit codes, 
> bash will do the job really well.
> 
> Good luck.
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Jenkins Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> For more options, visit https://groups.google.com/groups/opt_out.
>  
>  

-- 
You received this message because you are subscribed to the Google Groups 
"Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to