Запустите набор команд и верните код ошибки, если какой-либо сбой

Это из http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.13.html#rand :

Объявление:

void srand(unsigned int seed); 

Эта функция сгенерирует генератор случайных чисел, используемый функцией rand. Выселение srand с тем же семенем приведет к тому, что rand вернет ту же последовательность псевдослучайных чисел. Если srand не вызывается, rand действует так, как будто srand (1) был вызван.

0
задан SmxCde 18 January 2019 в 04:14
поделиться

1 ответ

То, что я хотел бы - выполнить все из них (чтобы все они печатали все ошибки) и только потом потерпеть неудачу

По сути, у нас есть список кодов выхода, которые нужно перехватить. Если какой-либо из них ненулевой, нам нужно установить переменную, которая будет иметь ненулевое значение. Расширение этого до списка выглядело бы так:

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.

0
ответ дан Kamil Cuk 18 January 2019 в 04:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: