2015-07-22 2 views
0

Мы создаем скрипт bash для сервера сборки. Мы хотим обеспечить, чтобы при выполнении команды bash внутри скрипта она возвращалась с сигналом 0. Если это не так, мы хотим, чтобы выполнение остановилось. Наше решение до сих пор сделать:Ловля всех плохих сигналов для вызываемых команд в сценарии Bash

#some command 
if [ $? -ne 0 ] ; then 
    #handle error 
fi 

после каждой команды, которая может вызвать эту проблему. Это делает код довольно длинным и не кажется очень изящным. Возможно, мы могли бы использовать функцию bash. Хотя работает с $? может быть немного сложнее, и нам все равно придется вызывать функцию после каждой команды. Есть ли способ лучше? Я просмотрел команду trap, но, похоже, обрабатывает только обработку сигналов с помощью сценария bash, который я пишу, а не любые команды, которые я вызываю.

+0

'$?' - это код выхода. Коды выхода и сигналы не связаны. –

ответ

2

Надежный, канонический способ сделать это:

#!/bin/bash 
die() { 
    local ret=$? 
    echo >&2 "$*" 
    exit "$ret" 
} 

./configure || die "Project can't be configured" 
make   || die "Project doesn't build" 
make install || die "Installation failed" 

Хрупкая, удобный способ сделать это set -e:

#!/bin/bash 
set -e  # Script will exit in many (but not all) cases if a command fails 

./configure 
make 
make install 

или что то же самое (с сообщением об ошибке):

#!/bin/bash 
# Will be called for many (but not all) commands that fail 
trap 'ret=$?; echo >&2 "Failure on line $LINENO, exiting."; exit $ret' ERR 

./configure 
make 
make install 

Для двух последних, сценарий не будет выходить за любую команду, которая является частью условного оператора или &&/||, так что пока:

backup() { 
    set -e 
    scp backup.tar.gz [email protected]:/backup 
    rm backup.tar.gz 
} 
backup 

правильно избежать выполнения rm, если передача не удается, а затем вставить функцию как это:

if backup 
then 
    mail -s "Backup completed successfully" [email protected] 
fi 

сделает backup остановку, выходящих на провал и случайное удаление резервных копий.

+0

Это работает! Спасибо за помощь. Я, вероятно, буду использовать третий. Охватывает ли ERR какой-либо ненулевой сигнал? Если да, могу ли я также использовать ловушки для других сигналов, например, отображать конкретное сообщение на SIGSEGV и иметь ли он приоритет над ловушкой ERR по умолчанию? – CodeBrewer

+0

ERR не обнаруживает никакого сигнала. Он запускается, когда команда возвращает ненулевой код выхода. Коды выхода и сигналы - это разные вещи. Процесс, убиваемый сигналом SIGSEGV (11), и процесс, выходящий с кодом 11, никоим образом не связан. –

+0

Хорошо. Мы будем держать это и недавние изменения в виду, когда мы делаем наши скрипты. – CodeBrewer

Смежные вопросы