Что бы я хотел - выполнить все из них (чтобы все они печатали все ошибки), и только после этого выполнить ошибку
В основном у нас есть список кодов выхода, которые нужно поймать. Если какой-либо из них ненулевой, нам нужно установить переменную, которая будет иметь ненулевое значение. Расширение этого до списка будет выглядеть следующим образом:
result=0
if ! lint_1; then result=1; fi
if ! lint_2; then result=1; fi
if ! lint_3; then result=1; fi
exit "$result"
Как программист, я вижу, что у нас здесь есть шаблон. Таким образом, мы можем использовать массив, но bash не имеет двухмерных массивов. Это был бы обходной путь с eval
для обхода указанных параметров. Это выполнимо. Вы должны использовать eval
, чтобы дважды вычислить массив «указатель» / имя, но работает. Обратите внимание, что eval
это evil
.
cmds_1=(lint_1 "arg with spaces you pass to lint_1")
cmds_2=(lint_2)
cmds_3=(lint_3)
result=0
# compgen results list of variables starting with `cmds_`
# so naming is important
for i in $(compgen -v cmds_); do
# at first, `$i` is only expanded
# then the array is expanded `"${cmds_?[@]}"`
if ! eval "\"\${$i[@]}\""; then
result=1
fi
done
exit "$result"
Мы также можем пойти с xargs . Из руководства EXIT STATUS
есть 123 if __any__ invocation of the command exited with status 1-125
. Если вы знаете, что ваши программы будут выходить из состояния выхода 1-125, то вы можете (обычно xargs в любом случае корректно обрабатывает различные состояния выхода (возвращает 123), но давайте оставаться в соответствии):
xargs -l1 -- bash -c '"$@"' -- <<EOF
lint_1 "arg with spaces you pass to lint_1"
lint_2
lint_3
EOF
result=$? # or just exit "$?"
exit "$result"
, который выглядит странно чистым. Кстати, передав только -P <number of jobs>
в xargs
, вы можете выполнить всю команду параллельно. Вы можете приспособиться к диапазону ошибок 1-125, обработав ошибку внутри скрипта bash, т. Е.
xargs -l1 -- bash -c '"$@" || exit 1' -- <<EOF
lint_1 "arg with spaces you pass to lint_1"
lint_2
lint_3
EOF
result=$?
exit "$result"
И у меня есть другая идея. После каждой команды мы можем вывести возвращаемый статус по выделенному файловому дескриптору. Затем из всех возвращаемых статусов отфильтруйте нули и проверьте, есть ли в потоке другие статусы. Если они есть, мы должны выйти с ненулевым статусом. Это похоже на проделанную работу и в основном соответствует первому фрагменту кода, но if ! ....; then result=1; fi
упрощено до ; echo $? >&10
.
tmp=$(mktemp)
(
lint_1 "arg with spaces you pass to lint_1"; echo $? >&10
lint_2; echo $? >&10
lint_3; echo $? >&10
) 10> >(
[ -z "$(grep -v 0)" ]
echo $? > "$tmp"
)
result="$(cat "$tmp"; rm "$tmp")"
exit "$result"
Из представленных вариантов я бы пошел с другим ответом;) или со вторым отсеченным xargs.