автоматический возврат исходного скрипта при сбое команды

автоматический возврат исходного скрипта при сбое команды

Как сделать так, чтобы sourceскрипт D автоматически возвращался в случае сбоя любой команды внутри него?

Предположим, у меня есть скрипт, который автоматически завершает работу при сбое set -e, например, через

#!/bin/bash
# foo.env
set -e        # auto-exit on any command failure
echo "hi"
grep 123 456  # this command will fail (I don't have a file named "456")
echo "should not reach here"

Если я запущу команду в обычном режиме, она автоматически завершится при неудачном выполнении grepкоманды:

box1% ./foo.env
hi
grep: 456: No such file or directory

Однако если я sourceзапущу скрипт, он выйдет из моей текущей оболочки, а не только из исходного скрипта:

box1% ssh box2
box2% source ./foo.env
hi
grep: 456: No such file or directory
Connection to box2 closed.
box1%

Если я удалю set -e,

#!/bin/bash
# foo2.env
echo "hi"
grep 123 456  # this command will fail (I don't have a file named "456")
echo "should not reach here"

sourceто он вообще не выходит автоматически и не возвращает автоматически скрипт d:

box1% ssh box2
box2% source ./foo2.env
hi
grep: 456: No such file or directory
should not reach here
box2%

Единственное решение, которое я нашел до сих пор, — это добавить returnвыражение в каждую строку кода в скрипте, например:

box1% cat foo3.env
#!/bin/bash
# foo3.env - works, but is cumbersome
echo "hi" || return
grep 123 456 || return
echo "should not reach here" || return

box1% source foo3.env
hi
grep: 456: No such file or directory
box1%

Есть ли другой способ для sourceскриптов на языке d, аналогичный тому, что set -eработает для не source-d скриптов?

решение1

Когда вы sourceсоздаете скрипт, это как если бы вы писали этот файл строка за строкой с клавиатуры. Это означает, что он set -eбудет учитывать текущую оболочку и что в случае ошибки он выйдет из текущей оболочки.

Это обходной путь. Сегодня я чувствую себя ленивым, поэтому я подумал, что компьютер может написать ||returnза меня, или, лучше, прочитать файл построчно и выполнить так:

#!/bin/bash
# this is the file MySource.sh
while IFS='' read -r line
do
   [[ $line == \#* ]] || $line || return
done < "$1"

выполнить его с. MySource.sh FileToBeSourced.sh

Если вашФайлToBeSourced.shСкрипт состоит из одной строки команд, он должен работать.
Далеко-далеко, чтобы быть готовым к использованию в производственной среде.
Протестируйте его и в конечном итогеИспользуйте его на свой страх и риск.

Он пропускает строки, начинающиеся с , #поскольку они должны вызывать ошибку # command not found.

Связанный контент