Bash Script: ловушки ошибок в блоке операторов

У меня есть большой набор правил iptables, который я управляю с помощью собственного скрипта bash. Большинство команд в скрипте являются простыми командами iptables с одним статусом. Я пытаюсь улучшить сценарий, добавив результат успеха / неудачи по мере выполнения скрипта.

У меня есть сценарий, разбитый на разные разделы. Одним из примеров может служить секция FORWARD, где все правила применяются к цепочке FORWARD. В начале раздела я выводил, что скрипт начал применять правила FORWARD, и в конце я хочу указать, были ли все правила применены успешно или если какой-либо из них не работал. Вот основная идея:

#Start FORWARD section echo -ne "Applying FORWARD rules..." #rule 1 /sbin/iptables -A FOWRARD... #rule 2 /sbin/iptables -A FORWARD... echo -ne "\t\t\t[OK]\n"

То, что я хочу сделать, это поймать любой вывод или ошибки, которые могут возникнуть в результате каждой команды iptables и хранить их в массиве или что-то в этом роде. Затем в конце блока используйте оператор if, чтобы оценить массив, чтобы увидеть, были ли какие-либо ошибки. Если нет, выведите состояние [OK], если они есть, выведите состояние [FAILED] и отобразите соответствующую ошибку.

Есть ли способ сделать это для всего блока правил, не обертывая каждый iptables в if, если [$? ! = 0] выражение?

4
задан 19 July 2011 в 22:54

18 ответов

Вы имеете в виду что-то вроде этого?

ok=1 #Start FORWARD section echo -ne "Applying FORWARD rules..." #rule 1 /sbin/iptables -A FOWRARD... || ok=0 #rule 2 /sbin/iptables -A FORWARD... || ok=0 echo -ne "\t\t\t" if [ $ok -eq 1 ]; then echo "[OK]" else echo "[fail]" fi
-1
ответ дан 25 July 2018 в 21:34

Вы можете использовать встроенную команду оболочки trap для вызова функции обработчика, если команда имеет ненулевой статус выхода. Вы можете передать необходимую информацию, такую ​​как номер строки и статус выхода, в вашу функцию обработчика ошибок.

Пример:

#!/bin/bash handle_error() { echo "FAILED: line $1, exit code $2" exit 1 } trap 'handle_error $LINENO $?' ERR # your commands here # ... echo "OK"
10
ответ дан 25 July 2018 в 21:34
  • 1
    За все годы моей битвы я никогда не слышал о команде ловушки! – Marco Ceppi♦ 20 July 2011 в 18:39
  • 2
    вы можете также: set -o errtrace на верхнем уровне скрипта, если вы также хотите, чтобы функции этого сценария вызывали эту ловушку в случае ошибок (в противном случае внутри функций эта ловушка не вызывалась) – Olivier Dulac 4 July 2014 в 14:12

Нижеприведенный скрипт определит функцию recordfailure, которая должна быть добавлена ​​к командам, как показано в примере после определения функции. Если команда возвращает ненулевое значение, регистрируется стандартный поток ошибок. Наконец, в конце, журнал ошибок проверяется и [OK] или [FAIL] печатаются соответствующим образом.

#!/bin/bash # Redirect file descriptor #3 to standard output (used in recordfailure) exec 3>&1 # create an array for holding failures declare -a failures # recordfailure command arg1 arg2 ... argN recordfailure() { local error retval # Run the command and store error messages (output to the standard error # stream in $error, but send regular output to file descriptor 3 which # redirects to standard output error="$("$@" 2>&1 >&3)" retval=$? # if the command failed (returned a non-zero exit code) if [ $retval -gt 0 ]; then if [ -z "$error" ]; then # create an error message if there was none error="Command failed with exit code $retval" fi # uncomment if you want the command in the error message #error="Command $* failed: $error" # append the error to $failures, ${#failures[@]} is the length of # the array and since array start at index 0, a new item is created failures[${#failures[@]}]="$error" # uncomment if you want to show the error immediately #echo "$error" fi } recordfailure iptables -A FORWARD ... recordfailure iptables -A FORWARD ... # if the length of the failures array equals 0 (no items) everything is OK if [ ${#failures[@]} -eq 0 ]; then echo "[OK]" else echo "[FAIL]" # list every error for failure in "${failures[@]}"; do # optionally color it, format it or whatever you want to do with it echo "error: $failure" done fi

Если у вас нет желания показывать стандартный вывод, удалите exec 3>&1 и замените >&3 на >/dev/null.

0
ответ дан 25 July 2018 в 21:34
  • 1
    Не тестируйте $? для истины или false, просто выполните команду в if в первую очередь. [F3]. О, и у вас есть запятая в команде local. – geirha 20 July 2011 в 18:10
  • 2
    @geirha: Я использую возвращаемое значение, если нет сообщения об ошибке. Если я использую if ! error=$("$@" 2>&1 >&3), я не могу оценить другое, если и отобразить возвращаемое значение. – Lekensteyn 20 July 2011 в 18:16
  • 3
    Уверен, что if проверяет возвращаемое значение команды, которую вы запускаете, а не выводит ли она что-либо в stderr. – geirha 20 July 2011 в 21:00

Вы имеете в виду что-то вроде этого?

ok=1 #Start FORWARD section echo -ne "Applying FORWARD rules..." #rule 1 /sbin/iptables -A FOWRARD... || ok=0 #rule 2 /sbin/iptables -A FORWARD... || ok=0 echo -ne "\t\t\t" if [ $ok -eq 1 ]; then echo "[OK]" else echo "[fail]" fi
-1
ответ дан 31 July 2018 в 12:45

Вы можете использовать встроенную команду оболочки trap для вызова функции обработчика, если команда имеет ненулевой статус выхода. Вы можете передать необходимую информацию, такую ​​как номер строки и статус выхода, в вашу функцию обработчика ошибок.

Пример:

#!/bin/bash handle_error() { echo "FAILED: line $1, exit code $2" exit 1 } trap 'handle_error $LINENO $?' ERR # your commands here # ... echo "OK"
10
ответ дан 31 July 2018 в 12:45
  • 1
    За все годы моей битвы я никогда не слышал о команде ловушки! – Marco Ceppi♦ 20 July 2011 в 18:39
  • 2
    вы можете также: set -o errtrace на верхнем уровне скрипта, если вы также хотите, чтобы функции этого сценария вызывали эту ловушку в случае ошибок (в противном случае внутри функций эта ловушка не вызывалась) – Olivier Dulac 4 July 2014 в 14:12

Нижеприведенный скрипт определит функцию recordfailure, которая должна быть добавлена ​​к командам, как показано в примере после определения функции. Если команда возвращает ненулевое значение, регистрируется стандартный поток ошибок. Наконец, в конце, журнал ошибок проверяется и [OK] или [FAIL] печатаются соответствующим образом.

#!/bin/bash # Redirect file descriptor #3 to standard output (used in recordfailure) exec 3>&1 # create an array for holding failures declare -a failures # recordfailure command arg1 arg2 ... argN recordfailure() { local error retval # Run the command and store error messages (output to the standard error # stream in $error, but send regular output to file descriptor 3 which # redirects to standard output error="$("$@" 2>&1 >&3)" retval=$? # if the command failed (returned a non-zero exit code) if [ $retval -gt 0 ]; then if [ -z "$error" ]; then # create an error message if there was none error="Command failed with exit code $retval" fi # uncomment if you want the command in the error message #error="Command $* failed: $error" # append the error to $failures, ${#failures[@]} is the length of # the array and since array start at index 0, a new item is created failures[${#failures[@]}]="$error" # uncomment if you want to show the error immediately #echo "$error" fi } recordfailure iptables -A FORWARD ... recordfailure iptables -A FORWARD ... # if the length of the failures array equals 0 (no items) everything is OK if [ ${#failures[@]} -eq 0 ]; then echo "[OK]" else echo "[FAIL]" # list every error for failure in "${failures[@]}"; do # optionally color it, format it or whatever you want to do with it echo "error: $failure" done fi

Если у вас нет желания показывать стандартный вывод, удалите exec 3>&1 и замените >&3 на >/dev/null.

0
ответ дан 31 July 2018 в 12:45
  • 1
    Не тестируйте $? для истины или false, просто выполните команду в if в первую очередь. [F3]. О, и у вас есть запятая в команде local. – geirha 20 July 2011 в 18:10
  • 2
    @geirha: Я использую возвращаемое значение, если нет сообщения об ошибке. Если я использую if ! error=$("$@" 2>&1 >&3), я не могу оценить другое, если и отобразить возвращаемое значение. – Lekensteyn 20 July 2011 в 18:16
  • 3
    Уверен, что if проверяет возвращаемое значение команды, которую вы запускаете, а не выводит ли она что-либо в stderr. – geirha 20 July 2011 в 21:00

Вы имеете в виду что-то вроде этого?

ok=1 #Start FORWARD section echo -ne "Applying FORWARD rules..." #rule 1 /sbin/iptables -A FOWRARD... || ok=0 #rule 2 /sbin/iptables -A FORWARD... || ok=0 echo -ne "\t\t\t" if [ $ok -eq 1 ]; then echo "[OK]" else echo "[fail]" fi
-1
ответ дан 2 August 2018 в 03:11

Вы можете использовать встроенную команду оболочки trap для вызова функции обработчика, если команда имеет ненулевой статус выхода. Вы можете передать необходимую информацию, такую ​​как номер строки и статус выхода, в вашу функцию обработчика ошибок.

Пример:

#!/bin/bash handle_error() { echo "FAILED: line $1, exit code $2" exit 1 } trap 'handle_error $LINENO $?' ERR # your commands here # ... echo "OK"
10
ответ дан 2 August 2018 в 03:11
  • 1
    За все годы моей битвы я никогда не слышал о команде ловушки! – Marco Ceppi♦ 20 July 2011 в 18:39
  • 2
    вы можете также: set -o errtrace на верхнем уровне скрипта, если вы также хотите, чтобы функции этого сценария вызывали эту ловушку в случае ошибок (в противном случае внутри функций эта ловушка не вызывалась) – Olivier Dulac 4 July 2014 в 14:12

Нижеприведенный скрипт определит функцию recordfailure, которая должна быть добавлена ​​к командам, как показано в примере после определения функции. Если команда возвращает ненулевое значение, регистрируется стандартный поток ошибок. Наконец, в конце, журнал ошибок проверяется и [OK] или [FAIL] печатаются соответствующим образом.

#!/bin/bash # Redirect file descriptor #3 to standard output (used in recordfailure) exec 3>&1 # create an array for holding failures declare -a failures # recordfailure command arg1 arg2 ... argN recordfailure() { local error retval # Run the command and store error messages (output to the standard error # stream in $error, but send regular output to file descriptor 3 which # redirects to standard output error="$("$@" 2>&1 >&3)" retval=$? # if the command failed (returned a non-zero exit code) if [ $retval -gt 0 ]; then if [ -z "$error" ]; then # create an error message if there was none error="Command failed with exit code $retval" fi # uncomment if you want the command in the error message #error="Command $* failed: $error" # append the error to $failures, ${#failures[@]} is the length of # the array and since array start at index 0, a new item is created failures[${#failures[@]}]="$error" # uncomment if you want to show the error immediately #echo "$error" fi } recordfailure iptables -A FORWARD ... recordfailure iptables -A FORWARD ... # if the length of the failures array equals 0 (no items) everything is OK if [ ${#failures[@]} -eq 0 ]; then echo "[OK]" else echo "[FAIL]" # list every error for failure in "${failures[@]}"; do # optionally color it, format it or whatever you want to do with it echo "error: $failure" done fi

Если у вас нет желания показывать стандартный вывод, удалите exec 3>&1 и замените >&3 на >/dev/null.

0
ответ дан 2 August 2018 в 03:11
  • 1
    Не тестируйте $? для истины или false, просто выполните команду в if в первую очередь. [F3]. О, и у вас есть запятая в команде local. – geirha 20 July 2011 в 18:10
  • 2
    @geirha: Я использую возвращаемое значение, если нет сообщения об ошибке. Если я использую if ! error=$("$@" 2>&1 >&3), я не могу оценить другое, если и отобразить возвращаемое значение. – Lekensteyn 20 July 2011 в 18:16
  • 3
    Уверен, что if проверяет возвращаемое значение команды, которую вы запускаете, а не выводит ли она что-либо в stderr. – geirha 20 July 2011 в 21:00

Вы имеете в виду что-то вроде этого?

ok=1 #Start FORWARD section echo -ne "Applying FORWARD rules..." #rule 1 /sbin/iptables -A FOWRARD... || ok=0 #rule 2 /sbin/iptables -A FORWARD... || ok=0 echo -ne "\t\t\t" if [ $ok -eq 1 ]; then echo "[OK]" else echo "[fail]" fi
-1
ответ дан 4 August 2018 в 19:04

Вы можете использовать встроенную команду оболочки trap для вызова функции обработчика, если команда имеет ненулевой статус выхода. Вы можете передать необходимую информацию, такую ​​как номер строки и статус выхода, в вашу функцию обработчика ошибок.

Пример:

#!/bin/bash handle_error() { echo "FAILED: line $1, exit code $2" exit 1 } trap 'handle_error $LINENO $?' ERR # your commands here # ... echo "OK"
10
ответ дан 4 August 2018 в 19:04
  • 1
    За все годы моей битвы я никогда не слышал о команде ловушки! – Marco Ceppi♦ 20 July 2011 в 18:39
  • 2
    вы можете также: set -o errtrace на верхнем уровне скрипта, если вы также хотите, чтобы функции этого сценария вызывали эту ловушку в случае ошибок (в противном случае внутри функций эта ловушка не вызывалась) – Olivier Dulac 4 July 2014 в 14:12

Нижеприведенный скрипт определит функцию recordfailure, которая должна быть добавлена ​​к командам, как показано в примере после определения функции. Если команда возвращает ненулевое значение, регистрируется стандартный поток ошибок. Наконец, в конце, журнал ошибок проверяется и [OK] или [FAIL] печатаются соответствующим образом.

#!/bin/bash # Redirect file descriptor #3 to standard output (used in recordfailure) exec 3>&1 # create an array for holding failures declare -a failures # recordfailure command arg1 arg2 ... argN recordfailure() { local error retval # Run the command and store error messages (output to the standard error # stream in $error, but send regular output to file descriptor 3 which # redirects to standard output error="$("$@" 2>&1 >&3)" retval=$? # if the command failed (returned a non-zero exit code) if [ $retval -gt 0 ]; then if [ -z "$error" ]; then # create an error message if there was none error="Command failed with exit code $retval" fi # uncomment if you want the command in the error message #error="Command $* failed: $error" # append the error to $failures, ${#failures[@]} is the length of # the array and since array start at index 0, a new item is created failures[${#failures[@]}]="$error" # uncomment if you want to show the error immediately #echo "$error" fi } recordfailure iptables -A FORWARD ... recordfailure iptables -A FORWARD ... # if the length of the failures array equals 0 (no items) everything is OK if [ ${#failures[@]} -eq 0 ]; then echo "[OK]" else echo "[FAIL]" # list every error for failure in "${failures[@]}"; do # optionally color it, format it or whatever you want to do with it echo "error: $failure" done fi

Если у вас нет желания показывать стандартный вывод, удалите exec 3>&1 и замените >&3 на >/dev/null.

0
ответ дан 4 August 2018 в 19:04
  • 1
    Не тестируйте $? для истины или false, просто выполните команду в if в первую очередь. [F3]. О, и у вас есть запятая в команде local. – geirha 20 July 2011 в 18:10
  • 2
    @geirha: Я использую возвращаемое значение, если нет сообщения об ошибке. Если я использую if ! error=$("$@" 2>&1 >&3), я не могу оценить другое, если и отобразить возвращаемое значение. – Lekensteyn 20 July 2011 в 18:16
  • 3
    Уверен, что if проверяет возвращаемое значение команды, которую вы запускаете, а не выводит ли она что-либо в stderr. – geirha 20 July 2011 в 21:00

Вы имеете в виду что-то вроде этого?

ok=1 #Start FORWARD section echo -ne "Applying FORWARD rules..." #rule 1 /sbin/iptables -A FOWRARD... || ok=0 #rule 2 /sbin/iptables -A FORWARD... || ok=0 echo -ne "\t\t\t" if [ $ok -eq 1 ]; then echo "[OK]" else echo "[fail]" fi
-1
ответ дан 6 August 2018 в 03:23

Вы можете использовать встроенную команду оболочки trap для вызова функции обработчика, если команда имеет ненулевой статус выхода. Вы можете передать необходимую информацию, такую ​​как номер строки и статус выхода, в вашу функцию обработчика ошибок.

Пример:

#!/bin/bash handle_error() { echo "FAILED: line $1, exit code $2" exit 1 } trap 'handle_error $LINENO $?' ERR # your commands here # ... echo "OK"
10
ответ дан 6 August 2018 в 03:23
  • 1
    За все годы моей битвы я никогда не слышал о команде ловушки! – Marco Ceppi♦ 20 July 2011 в 18:39
  • 2
    вы можете также: set -o errtrace на верхнем уровне скрипта, если вы также хотите, чтобы функции этого сценария вызывали эту ловушку в случае ошибок (в противном случае внутри функций эта ловушка не вызывалась) – Olivier Dulac 4 July 2014 в 14:12

Нижеприведенный скрипт определит функцию recordfailure, которая должна быть добавлена ​​к командам, как показано в примере после определения функции. Если команда возвращает ненулевое значение, регистрируется стандартный поток ошибок. Наконец, в конце, журнал ошибок проверяется и [OK] или [FAIL] печатаются соответствующим образом.

#!/bin/bash # Redirect file descriptor #3 to standard output (used in recordfailure) exec 3>&1 # create an array for holding failures declare -a failures # recordfailure command arg1 arg2 ... argN recordfailure() { local error retval # Run the command and store error messages (output to the standard error # stream in $error, but send regular output to file descriptor 3 which # redirects to standard output error="$("$@" 2>&1 >&3)" retval=$? # if the command failed (returned a non-zero exit code) if [ $retval -gt 0 ]; then if [ -z "$error" ]; then # create an error message if there was none error="Command failed with exit code $retval" fi # uncomment if you want the command in the error message #error="Command $* failed: $error" # append the error to $failures, ${#failures[@]} is the length of # the array and since array start at index 0, a new item is created failures[${#failures[@]}]="$error" # uncomment if you want to show the error immediately #echo "$error" fi } recordfailure iptables -A FORWARD ... recordfailure iptables -A FORWARD ... # if the length of the failures array equals 0 (no items) everything is OK if [ ${#failures[@]} -eq 0 ]; then echo "[OK]" else echo "[FAIL]" # list every error for failure in "${failures[@]}"; do # optionally color it, format it or whatever you want to do with it echo "error: $failure" done fi

Если у вас нет желания показывать стандартный вывод, удалите exec 3>&1 и замените >&3 на >/dev/null.

0
ответ дан 6 August 2018 в 03:23
  • 1
    Не тестируйте $? для истины или false, просто выполните команду в if в первую очередь. [F3]. О, и у вас есть запятая в команде local. – geirha 20 July 2011 в 18:10
  • 2
    @geirha: Я использую возвращаемое значение, если нет сообщения об ошибке. Если я использую if ! error=$("$@" 2>&1 >&3), я не могу оценить другое, если и отобразить возвращаемое значение. – Lekensteyn 20 July 2011 в 18:16
  • 3
    Уверен, что if проверяет возвращаемое значение команды, которую вы запускаете, а не выводит ли она что-либо в stderr. – geirha 20 July 2011 в 21:00

Вы имеете в виду что-то вроде этого?

ok=1 #Start FORWARD section echo -ne "Applying FORWARD rules..." #rule 1 /sbin/iptables -A FOWRARD... || ok=0 #rule 2 /sbin/iptables -A FORWARD... || ok=0 echo -ne "\t\t\t" if [ $ok -eq 1 ]; then echo "[OK]" else echo "[fail]" fi
-1
ответ дан 7 August 2018 в 21:09

Вы можете использовать встроенную команду оболочки trap для вызова функции обработчика, если команда имеет ненулевой статус выхода. Вы можете передать необходимую информацию, такую ​​как номер строки и статус выхода, в вашу функцию обработчика ошибок.

Пример:

#!/bin/bash handle_error() { echo "FAILED: line $1, exit code $2" exit 1 } trap 'handle_error $LINENO $?' ERR # your commands here # ... echo "OK"
10
ответ дан 7 August 2018 в 21:09
  • 1
    За все годы моей битвы я никогда не слышал о команде ловушки! – Marco Ceppi♦ 20 July 2011 в 18:39
  • 2
    вы можете также: set -o errtrace на верхнем уровне скрипта, если вы также хотите, чтобы функции этого сценария вызывали эту ловушку в случае ошибок (в противном случае внутри функций эта ловушка не вызывалась) – Olivier Dulac 4 July 2014 в 14:12

Нижеприведенный скрипт определит функцию recordfailure, которая должна быть добавлена ​​к командам, как показано в примере после определения функции. Если команда возвращает ненулевое значение, регистрируется стандартный поток ошибок. Наконец, в конце, журнал ошибок проверяется и [OK] или [FAIL] печатаются соответствующим образом.

#!/bin/bash # Redirect file descriptor #3 to standard output (used in recordfailure) exec 3>&1 # create an array for holding failures declare -a failures # recordfailure command arg1 arg2 ... argN recordfailure() { local error retval # Run the command and store error messages (output to the standard error # stream in $error, but send regular output to file descriptor 3 which # redirects to standard output error="$("$@" 2>&1 >&3)" retval=$? # if the command failed (returned a non-zero exit code) if [ $retval -gt 0 ]; then if [ -z "$error" ]; then # create an error message if there was none error="Command failed with exit code $retval" fi # uncomment if you want the command in the error message #error="Command $* failed: $error" # append the error to $failures, ${#failures[@]} is the length of # the array and since array start at index 0, a new item is created failures[${#failures[@]}]="$error" # uncomment if you want to show the error immediately #echo "$error" fi } recordfailure iptables -A FORWARD ... recordfailure iptables -A FORWARD ... # if the length of the failures array equals 0 (no items) everything is OK if [ ${#failures[@]} -eq 0 ]; then echo "[OK]" else echo "[FAIL]" # list every error for failure in "${failures[@]}"; do # optionally color it, format it or whatever you want to do with it echo "error: $failure" done fi

Если у вас нет желания показывать стандартный вывод, удалите exec 3>&1 и замените >&3 на >/dev/null.

0
ответ дан 7 August 2018 в 21:09
  • 1
    Не тестируйте $? для истины или false, просто выполните команду в if в первую очередь. [F3]. О, и у вас есть запятая в команде local. – geirha 20 July 2011 в 18:10
  • 2
    @geirha: Я использую возвращаемое значение, если нет сообщения об ошибке. Если я использую if ! error=$("$@" 2>&1 >&3), я не могу оценить другое, если и отобразить возвращаемое значение. – Lekensteyn 20 July 2011 в 18:16
  • 3
    Уверен, что if проверяет возвращаемое значение команды, которую вы запускаете, а не выводит ли она что-либо в stderr. – geirha 20 July 2011 в 21:00

Другие вопросы по тегам:

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