У меня проблема с проверкой того, действительно ли какая-то команда в цепочке команд с несколькими трубами выбрасывает ошибку. Обычно это не сложно проверить, но ни set -o pipefail
, ни проверка ${PIPESTATUS[@]}
работает в моем случае. Настройка такова:Bash: проверка состояния выхода для многотрубной цепочки команд
cmd="$snmpcmd $snmpargs $agent $oid | grep <grepoptions> for_stuff | cut -d',' f$fields | sed 's/ubstitute/some_other_stuff/g'"
Примечание: 1 команда была проверена полностью и отлично работает.
Теперь я хочу сохранить вывод этой команды в массиве с именем procdata
. Таким образом, я сделал:
declare -a procdata
procdata=($(eval $cmd))
Note-2: eval
необходимо, потому что в противном случае $snmpcmd
подбрасывает с invalid option -- <grepoption>
ошибкой, которая не имеет никакого смысла, потому что <grepoption>
не является $snmpcmd
вариант, очевидно. На этом этапе я считаю ошибку ошибкой с $snmpcmd
, но это еще одно шоу ...
При возникновении ошибки procdata
будет пустым. Однако он может быть пустым по двум причинам: либо из-за ошибки при выполнении $snmpcmd
(например, таймаута), либо потому, что grep
не смог найти то, что искал. Проблема в том, что мне нужно иметь возможность различать эти два случая и обрабатывать их отдельно.
Таким образом, set -o pipefail
не является вариантом, так как он будет распространять любую ошибку, и я не могу различить, какая часть трубы не удалась. С другой стороны, echo ${PIPESTATUS[@]}
всегда 0
после procdata=($(eval $cmd))
, хотя у меня много труб!?. Тем не менее, если я выполняю всю команду непосредственно в приглашении и сразу вызываю echo ${PIPESTATUS[@]}
, он правильно возвращает статус выхода всех каналов.
Я знаю, что могу связать поток err с stdout, но мне нужно будет использовать эвристические методы, чтобы проверить, являются ли элементы в procdata
действительными или сообщениями об ошибках, и я рискую получить ложные срабатывания. Я мог бы также вывести stdout на /dev/null
и захватить только поток ошибок и проверить, ${#procdata[@]} -eq 0
. Но мне пришлось бы повторить звонок, чтобы получить фактические данные, и вся команда будет дорогостоящей (около 3-5 секунд). Я бы не хотел называть это дважды. Или я мог бы использовать временный файл для записи ошибок, но я бы предпочел сделать это без накладных расходов на создание/удаление файлов.
Любые идеи, как я могу сделать эту работу в bash?
Благодаря
PS:
$ echo $BASH_VERSION
4.2.37(1)-release
Я была такая же мысль. К сожалению, это тоже не работает, но я не знаю, почему. Я отправляю точные команды, потому что я не вижу очевидного: – user3040975
'local cmdargs =" - CHf, -m $ mibs -v $ snmpver -c $ community $ agent "; local procdatacmd = "$ tblcmd $ cmdargs $ proc_table"; procdatacmd + = "| cut -d ',' -f $ fields | grep -we -e | sort | uniq -c | sed 's/^ * \ | \" // g; s//,/g' ; echo $ {PIPESTATUS [@]} "'. Тогда я делаю: 'declare -a procdata = ($ (head -n -1 <<< $ procdatacmd))'. Выход пуст ... просто ничего. и ... –
user3040975
@ user3040975 Вы не являетесь _running_ любой командой в строке выше. – devnull