コマンド失敗時に `source` されたスクリプトを自動的に返す

コマンド失敗時に `source` されたスクリプトを自動的に返す

sourced スクリプト内のいずれかのコマンドが失敗した場合にスクリプトが自動的に戻るようにするにはどうすればよいですか?

例えば、失敗したときに自動的に終了するスクリプトがあるとします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"

すると、d スクリプトは自動的に終了したり自動的に返されたりしなくなりますsource

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%

非 d スクリプトのsource場合と同様に、 d スクリプトでも別の方法がありますか?set -esource

答え1

スクリプトを実行すると、sourceキーボードからファイルを 1 行ずつ書き込んでいるかのようになります。つまり、set -e現在のシェルが考慮され、エラーが発生すると現在のシェルが終了します。

||returnこれは回避策です。今日は怠け者なので、コンピューターが代わりに書いてくれるか、ファイルを 1 行ずつ読み取って実行してくれるといいな と思いました。

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

実行する. MySource.sh FileToBeSourced.sh

もしあなたのファイルソース.shスクリプトは 1 行のコマンドで動作するはずです。
実稼働環境で使用できるようになるまでには、まだ遠い道のりがあります。
テストして、最終的に自己責任でご利用ください

で始まる行は#エラーの原因となるためスキップします# command not found

関連情報