开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜