私はbashスクリプトを書いていて、スクリプトがwhile
ループでの入力を待っている間に、コードを更新(スクリプトファイルをディスクに保存)していました。ターミナルに戻って前回のスクリプトの呼び出しを続行した後、bashはファイルの構文に関するエラーを出しました。
/home/aularon/bin/script: line 58: unexpected EOF while looking for matching `"'
/home/aularon/bin/script: line 67: syntax error: unexpected end of file
だから私は次のことをやってみました:
1つ目:スクリプトを作成し、self-update.sh
呼び出しましょう。
#!/bin/bash
fname=$(mktemp)
cat $0 | sed 's/BEFORE\./AFTER!./' > $fname
cp $fname $0
rm -f $fname
echo 'String: BEFORE.';
スクリプトが行うことは、コードを読み取り、「BEFORE」という単語を「AFTER」に変更してから、新しいコードで自分自身を書き直すことです。
2回実行:
chmod +x self-update.sh
./self-update.sh
第三不思議...
aularon@aularon-laptop:~$ ./self-update.sh
String: AFTER!.
今、私は同じ呼び出しでAFTERが出力されるとは思っていませんでした!、確かに2回目の実行では、最初の実行ではありません。
だから私の質問は、それは意図的なものですか?それともbashがスクリプトを実行する方法が原因ですか?行ごとまたはコマンドごと。そのような行動の良い使い方はありますか?その例は?
編集:ファイルを再フォーマットしてすべてのコマンドを1行に入れようとしましたが、現在は機能しません。
#!/bin/bash
fname=$(mktemp);cat $0 | sed 's/BEFORE\./AFTER!./' > $fname;cp $fname $0;rm -f $fname;echo 'String: BEFORE.';
出力:
aularon@aularon-laptop:~$ ./self-update.sh #First invocation
String: BEFORE.
aularon@aularon-laptop:~$ ./self-update.sh #Second invocation
String: AFTER!.
echo
文字列を次の行に移動するときに、それを書き換え(cp
)呼び出しから分離します。
#!/bin/bash
fname=$(mktemp);cat $0 | sed 's/BEFORE\./AFTER!./' > $fname;cp $fname $0;rm -f $fname;
echo 'String: BEFORE.';
そして今それは再び動作します:
aularon@aularon-laptop:~$ ./self-update.sh
String: AFTER!.