ファイルから読み込み、内容を1行ずつ実行します。最初のエラーが発生すると終了します。

ファイルから読み込み、内容を1行ずつ実行します。最初のエラーが発生すると終了します。

do.sh私はファイルの内容を読むためにbashコマンドライン設定を使用しています。このファイルの各行を1行ずつ実行して、後で中間行のエラーを処理し、後続の内容の実行を停止するスクリプトにテキストを追加できるようにします。私が使用する構文は次のとおりです。

cat do.sh|while read lin;do (echo $(" $lin")) ;done
echo $amit

do.shの内容が次のようになるとします。

amit=3
ram=/path/to/some/dir
ls >> amit.log

amit最後に、2つの変数(たとえば、、)の内容にアクセスできる必要があり、ramコマンドの出力はエラーを特定できません。lsに保存する必要があります。amit.log

答え1

標準の getpoint スクリプトの使用

. ./do.sh

または非標準

source ./do.sh

...スクリプトを実行し、生成された変数を現在の環境に保持する方法(そして出力を含むファイルを生成する方法ls)だけを要求する元の質問を解決します。

更新された質問では、エラーが発生したときにスクリプトソースをすぐに終了する方法についても尋ねます。 「エラー」は、一部のコマンドがゼロ以外の終了状態で終了したことを意味すると仮定します。

set -e通常、最初のエラーで終了するようにアクティブなスクリプトを実行できますが、スクリプトは必ず源泉、私たちはこれを行うことはできません(現在のシェルを終了します)。代わりに、bashコマンドがゼロ以外の終了状態で終了したときに任意のコマンドを即座に実行できる関数を使用できます。実行しようとするコマンドは、returnエラーが発生するとすぐに実行されます。これによりスクリプトの実行が停止し、$?現在のシェルの終了ステータスが返されます。

だから:

trap 'err=$?; trap - ERR; return "$err"' ERR
. ./do.sh
trap - ERR

これによりERRトラップがコマンドに設定されますerr=$?; trap - ERR; return "$err"。このコマンドはすべてのエラーに対して実行され、終了ステータスをに保存し、トラップをオンにし、エラーをシェルerrに返します$?(終了ステータスも変数に保持しますerr)。最後に、トラップをデフォルト値にtrap - ERRリセットします。ERR

例:

false失敗したコマンドのシミュレーションに使用した呼び出しを含めるようにスクリプトが変更されました。変数は設定されますが、amit.logファイルは生成されません。

$ cat do.sh
amit=3
ram=/path/to/some/dir
false
ls >> amit.log

次のコマンドを実行してください。

$ trap 'err=$?;trap - ERR;return "$err"' ERR
$ . ./do.sh
$ trap - ERR

変数を取得しましたが、ファイルがまだ作成されていないことを示します。

$ printf '%s\n' "$amit" "$ram"
3
/path/to/some/dir
$ ls
do.sh

答え2

do.shから変数を取得するには、この方法を使用します。

#!/bin/bash

. ./do.sh

echo "$amit $ram"

.のコマンドは、./do.shdo.shに設定されているすべての変数にアクセスできるように、現在の環境でファイルを実行するようにインタプリタに指示します。

答え3

いくつかの問題:

  • サブシェルでコマンドを実行しています。サブシェル環境の変更は親シェルに伝播されません。
  • あなたは何も割り当てません。割り当ては変数拡張の前に行われるため、拡張時に割り当てではなく" $lin"コマンドとして理解されます。$(...)つまり、amit=3次のように入力したように、名前付きコマンドを実行しようとします"amit=3"そして引用符)。
    PS:引用符を省略してもdo (echo $(" $lin"))役に立ちません。試してはいけません。
  • パイプラインでプロセス全体を実行しています。それ以外の場合は、lastpipeサブシェルで再実行されます。つまり、変更は親シェルに伝播されません。

これにより、すべての問題が解決されました。

#!/bin/bash
shopt -s lastpipe
cat do.sh | while read lin ; do
    eval "$lin"
done

echo "$amit $ram"

しかし、問題が発生します。誰かが含めるようにファイルを変更するとどうなりますかrm -rf *

答え4

[root@x ~]# cat /tmp/sk221
amit=3
ram=/tmp/sk12

[root@x ~]# . /tmp/sk221

[root@x ~]# echo $amit
3

[root@x ~]# echo $ram
/tmp/sk12

関連情報