How to extract bits from return code number in Bash
I am using pylint utility that returns this error codes:
Pylint should leave with following status code:
* 0 if everything went fine
* 1 if a fatal message was issued
* 2 if an error message was issued
* 4 if a warning message was issued
* 8 if a refactor message was issued
* 16 if a convention message was issued
* 32 on usage error
status 1 to 16 will be bit-ORed so you can know which different
categories has been issued by analysing pylint output status code
开发者_C百科
Now I need to determine if fatal or error message occured in Bash. How to do that? I guess I need bit operations for that ;-)
Edit: I know I need to do bitwise and with number three (3) and test against null to see if fatal message or error message were issued. My problem is simple: bash syntax to do it. Input is $?, ouptut is again $? (e.g. using test program). Thanks!
in Bash you can use double parenthesis:
#fatal error
errorcode=7
(( res = errorcode & 3 ))
[[ $res != 0 ]] && echo "Fatal Error"
Bash supports bitwise operators...
$ let "x = 5>>1"
$ echo $x
2
$ let "x = 5 & 4"
$ echo $x
4
A fatal message will be issued iff the status is odd, iff it has a 1 in the least significant digit.
An error message will be issued iff the status has a 1 in the next most significant digit.
So you want to check whether the last two digits are both 1; in other words, to check whether the bitwise and
of your status code with 0b11
is three.
Got it!
[ $(($NUMBER & 3)) -ne 0 ] && echo Fatal error or error was issued
Thanks!
To embed something like this in a script with errexit
set, you could use a form like the following:
#!/bin/bash
set -o errexit
set -o nounset
(
rc=0;
pylint args args || rc=$?;
exit $(( $rc & 35 )) # fatal=1 | error=2 | usage error=32
)
Inspired from David's comment and this answer
You could poke at it by replacing the pylint blah blah
with python -c "exit(4+8+16)"
The return code of the last executed command in bash is available as $?
.
[/tmp] % touch bar
[/tmp] % ls /tmp/bar
/tmp/bar
[/tmp] % echo $?
0
[/tmp] % ls /tmp/baaz
ls: /tmp/baaz: No such file or directory
[/tmp] % echo $?
1
[/tmp] %
If you were to call an external command from say python's subprocess
module, you could get the return code of the external command from the Popen object once the subprocess has exited.
Using (probably sub-optimally) the bash arithmetic stuff:
for status in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
do
if [ $status = 0 ]
then echo $status: it worked perfectly
elsif [ $(( $status & 3 )) != 0 ]
then echo $status: a fatal or error message was sent
else echo $status: it sort of worked mostly
fi
done
Output:
0: it worked perfectly
1: a fatal or error message was sent
2: a fatal or error message was sent
3: a fatal or error message was sent
4: it sort of worked mostly
5: a fatal or error message was sent
6: a fatal or error message was sent
7: a fatal or error message was sent
8: it sort of worked mostly
9: a fatal or error message was sent
10: a fatal or error message was sent
11: a fatal or error message was sent
12: it sort of worked mostly
13: a fatal or error message was sent
14: a fatal or error message was sent
15: a fatal or error message was sent
16: it sort of worked mostly
I strongly suspect that the scripting (testing) can be made tighter or cleaner (specifically in the elif
clause), but this seems to work (and I need to get to work).
pylint ...
status=$? # Catch exit status before it changes
if [ $status = 0 ]
then echo $status: it worked perfectly
elsif [ $(( $status & 3 )) != 0 ]
then echo $status: a fatal or error message was sent
else echo $status: it sort of worked mostly
fi
精彩评论