
ループされたbashスクリプトがメモリにロードされているように見えることもありますが、ディスクから読み続けるように見えることもあります。些細なスクリプトでは、これが起こるかどうかはわかりません。
通常、これは実際には重要ではありませんが、スクリプトを変更すると、変更を保存すると実行中のスクリプトが破損することがあります(常にそうではありません)。明らかにスクリプトの特定のポイントから始まるからです。そして読んでいる内容はもはや彼らが去ったときと同じではありません!
だから私は尋ねたかった。スクリプトがメモリ内で実行されず、ディスクから継続的に読み取られるかどうかを知る方法はありますか?
abc
この単純なスクリプトは、変更とxyz
保存がスクリプトの実行中のインスタンスに影響を与えないため、完全にメモリから読み取られ実行されるように見えます。
#!/usr/bin/env bash
while :
do
echo abc
sleep 2
done
たぶんちょうどサイズの問題ですか?
答え1
これは部分的にサイズの問題です。通常のファイルから読み取ると、BashはCライブラリが実行するのと同じように一度に1つのブロックを読み取ります(一度に数キロバイトにすることができます)。次に、得られたすべての完全な行を解析し、すべての操作を実行します。十分コマンドがあります。ただし、読み取りポインタも中断された場所に返されるため、ファイルが小さい場合でもファイルの変更を確認できます。 (常に後ろを振り返るわけではないようです。外部コマンドを実行するときにのみこれを行うかどうかはわかりません。)
だからあなたがこれを持っている場合:
echo one
sleep 123
# filler if needed
echo two
echo
スリープ中にファイルを内部で編集すると、Bashはそのファイルを読み取って実行する前に2番目のファイルを変更できます。他のいくつかのシェル(DashやBusyboxなど)は読み取りポインタを振り返らないため、コマンド間に数キロバイトの大きなパディングがある場合にのみ効果が得られます。
ただし、次の場合
main() {
echo one
sleep 123
# really long multi-kB comment
# ...
echo two
}
main
シェルは関数を一度読み込んで保存し、メモリから実行します。
「あなた」という慣用語がまたあります。
main "$@"; exit
ファイルの最後の行に。 Bashは一度に行全体を読み込んで解析するので、後でファイルが変更されてもシェルがメイン関数の後に終了することを保証します。
以前は以下に別の答えを書いたようです。ランタイム代替シェルスクリプト。そこには自己修正スクリプトの例があります。