Как извлечь бит из номера кода возврата в Bash - PullRequest
4 голосов
/ 08 июля 2011

Я использую утилиту pylint, которая возвращает коды ошибок:

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

Теперь мне нужно определить, произошло ли неустранимое сообщение об ошибке в Bash. Как это сделать? Я думаю, мне нужны битовые операции для этого; -)

Редактировать : я знаю, что мне нужно сделать побитовое и с номером три (3) и проверить нулевое значение, чтобы увидеть, были ли выведены фатальные сообщения или сообщения об ошибках. Моя проблема проста: синтаксис bash для этого . Ввод $ ?, выход снова $? (например, с использованием тестовой программы). Спасибо!

Ответы [ 7 ]

3 голосов
/ 08 июля 2011

в Bash вы можете использовать двойные скобки:

#fatal error
errorcode=7
(( res = errorcode & 3 ))
[[ $res != 0 ]] && echo "Fatal Error"
2 голосов
/ 08 июля 2011

Понял!

[ $(($NUMBER & 3)) -ne 0 ] && echo Fatal error or error was issued

Спасибо!

2 голосов
/ 08 июля 2011

Неустранимое сообщение будет выдано, если статус нечетный, если он имеет 1 в младшей значащей цифре.

Будет выдано сообщение об ошибке, если статус имеет 1 в следующей самой значимой цифре.

Итак, вы хотите проверить, равны ли последние две цифры 1;другими словами, чтобы проверить, равны ли поразрядные and вашего кода состояния с 0b11 тремя.

2 голосов
/ 08 июля 2011

Bash поддерживает побитовые операторы ...

$ let "x = 5>>1"
$ echo $x
2
$ let "x = 5 & 4"
$ echo $x
4
1 голос
/ 18 апреля 2018

Чтобы встроить что-то подобное в скрипт с установленным errexit, вы можете использовать форму, подобную следующей:

#!/bin/bash
set -o errexit
set -o nounset
(
    rc=0;
    pylint args args || rc=$?;
    exit $(( $rc & 35 )) # fatal=1 | error=2 | usage error=32
)

Вдохновленный комментарием Дэвида и этимответ

Вы можете ткнуть в него, заменив pylint blah blah на python -c "exit(4+8+16)"

1 голос
/ 08 июля 2011

Код возврата последней выполненной команды в bash доступен как $?.

[/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] % 

Если бы вы вызывали внешнюю команду из модуля subprocess, скажем, Python, вы можете получить код возврата внешней команды из объекта Popen после выхода из подпроцесса.

0 голосов
/ 08 июля 2011

Использование (возможно, неоптимально) арифметики bash:

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

Выход:

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

Я сильно подозреваю, что скриптинг (тестирование) можно сделать более жестким или более чистым (в частности, в предложении elif), но, похоже, это работает (и мне нужно приступить к работе).

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
...