サブシェルスクリプトの反復制御フロー

サブシェルスクリプトの反復制御フロー

他のスクリプト(B)によって呼び出されるシェルスクリプト(A)があります。このスクリプト(A)では、残りのスクリプトが正しく機能する準備ができていくつかのディレクトリを作成し、いくつかのファイルを移動しました。スクリプト (A) はスクリプト (B) によって反復的な方法で呼び出され、最初のループ中にディレクトリの作成とファイルの移動が一度だけ発生したいと思います。

スクリプトの一部を一度だけ実行するにはどうすればよいですか?

答え1

呼び出しスクリプトから呼び出しスクリプトにこの情報を渡す方法はいくつかあります。 1つは、パラメータ(./script --initvs. ./script)またはパラメータ値(./script --init=0vs.)を使用することです./script --init=1。最も簡単な方法は、環境変数を使用することです。

スクリプトB:

init=0
while whatever; do INIT=$((init++)) ./script_A; done

スクリプトA:

[...]
if [ 0 -eq "$INIT" ]; then
  : make preparations
fi
[...]

スクリプトAがスクリプトBの呼び出しなしで実行できる場合は、欠落している変数を処理する必要があります(ifもちろんステートメントの前)。

: ${INIT:=1}

答え2

依存するには、比較的ユニークな環境品質が必要です。これは実装が容易ではありません。特に、ループ内で別々のスクリプトを繰り返し呼び出して、表示されるたびに異なる動作をすることを期待している場合は、さらにそうです。(この場合、同じスクリプトの一部を使用しないのはなぜですか?)

それにもかかわらず、一般的な慣行は、これらのタスクを実行するためにロックファイルまたは同様のファイルを使用することです。しかし、そのためにはユニークな環境が必要です。以下を考慮してください。

sh -c 'echo "$PPID" "$$"
       for i in 1 2 3 4 5
       do sh -c "echo \"\$PPID\""
       done'

出力

25711 28929
28929
28929
28929
28929
28929

環境変数にpidを提供するために呼び出し元が依存できる場合は、$PPIDそれがあなたが必要とする可能性があります。たとえば、

#!/bin/sh
#script a
LOCKDIR=${TMPDIR:-/tmp}/${0##*/}.$PPID

init() { mkdir "$LOCKDIR" || exit
#        do other initialization tasks
}

loop() { : do the iterable tasks here; }

[ -d "$LOCKDIR" ] || init
loop

...そして...

#!/bin/sh
#script b
a='/path/to/script/a'
for stuff in $things
do "$a" "$stuff"
done
rm -rf "${TMPDIR:-/tmp}/${a##*/}.$$"

しかし、真剣に、私はこのようなことをするのが良い考えである状況にあまり触れませんでした。別のシェルスクリプトを繰り返し呼び出して環境に依存する必要がある場合は、次.の内容をソースとして取得できます。スクリプトを現在のシェルに入れて、そのように実行します。私はそうします。つまり、もしそうだったら非常に実行中のスクリプトが安全に作成されていることを確認してください。

答え3

ifステートメントのトリガーとして行番号を使用したトリガーテキストファイルを作成し、ifステートメント内のテキストファイルを編集してより多くの行を追加しました。これにより、繰り返し回数に関係なく、ifステートメントは一度だけ実行されます。非常に簡単なコードで解決可能です。 Trigger.txt n=$(wc -l > Trigger.txt fi をタッチします。

関連情報