tail ブロックしません
いつものように、すべてについて、短く、理解しやすく、従うのが簡単で、完全に間違っている答えがあります.こちら tail -f /dev/null このカテゴリに分類されます;)
strace tail -f /dev/null で見ると このソリューションはブロックにはほど遠いことに気付くでしょう。おそらく sleep よりもさらに悪いです inotify のような (Linux の下で) 貴重なリソースを使用するため、問題の解決策 システム。 /dev/null に書き込む他のプロセスも tail にする ループ。 (私の Ubuntu64 16.10 では、これにより、既にビジー状態のシステムに 1 秒あたり 10 回のシステムコールが追加されます。)
問題はブロッキング コマンドでした
残念ながらそんなことはありません..
読む:これをシェルで直接アーカイブする方法がわかりません。
すべて (sleep infinity でも) ) 何らかの信号によって中断される可能性があります。したがって、例外的に返されないことを本当に確認したい場合は、 sleep で既に行ったように、ループで実行する必要があります . (Linux では) /bin/sleep であることに注意してください。 明らかに 24 日間が上限です (strace sleep infinity を見てください)。 )、したがって、おそらくできる最善のことは次のとおりです。
while :; do sleep 2073600; done
(私は sleep を信じていることに注意してください) は 24 日を超える値に対して内部的にループしますが、これは次のことを意味します。ブロックしているのではなく、非常にゆっくりとループしています。では、このループを外側に移動してみませんか?)
..しかし、名前のない fifo でかなり近づくことができます
プロセスにシグナルが送信されない限り、実際にブロックするものを作成できます。以下は bash 4 を使用しています 、2 つの PID と 1 つの fifo :
bash -c 'coproc { exec >&-; read; }; eval exec "${COPROC[0]}<&-"; wait'
strace でこれが実際にブロックされていることを確認できます よろしければ:
strace -ff bash -c '..see above..'
これがどのように構築されたか
read 入力データがない場合はブロックします(他の回答を参照してください)。ただし、tty (別名 stdin ) は、ユーザーがログアウトすると閉じられるため、通常は適切なソースではありません。また、tty からの入力を盗む可能性もあります。 .良くない。
read にする fifo のようなものを待つ必要があります。 これは何も返しません。 bash 4 で そのような fifo を正確に提供できるコマンドがあります :coproc .ブロッキング read も待つ場合 (これは coproc です )、これで完了です。悲しいことに、これは 2 つの PID と fifo を開いたままにしておく必要があります .
fifo という名前のバリアント
名前付きの fifo をわざわざ使用しない場合 、これは次のように行うことができます:
mkfifo "$HOME/.pause.fifo" 2>/dev/null; read <"$HOME/.pause.fifo"
読み取りでループを使用しないのは少しずさんですが、この fifo を再利用できます 好きなだけ read を作ってください touch "$HOME/.pause.fifo" を使用した終端 (複数の読み取り待機がある場合は、すべてが一度に終了します)。
または Linux pause() を使用します システムコール
無限ブロッキングには、pause() と呼ばれる Linux カーネル呼び出しがあります。 、これは私たちが望むことを行います:永遠に (シグナルが到着するまで) 待ちます。ただし、このためのユーザー空間プログラムは (まだ) ありません。
C
このようなプログラムを作成するのは簡単です。 pause という非常に小さな Linux プログラムを作成するためのスニペットを次に示します。 無期限に一時停止します (diet が必要です) 、 gcc など):
printf '#include <unistd.h>\nint main(){for(;;)pause();}' > pause.c;
diet -Os cc pause.c -o pause;
strip -s pause;
ls -al pause
python
自分で何かをコンパイルしたくないが、python がある場合 これを Linux で使用できます:
python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'
(注:exec python -c ... を使用してください 現在のシェルを置き換えるために、これにより 1 つの PID が解放されます。このソリューションは、未使用の FD を解放して、いくつかの IO リダイレクトでも改善できます。これはあなた次第です。)
これがどのように機能するか (私は思う):ctypes.CDLL(None) 標準 C ライブラリをロードし、pause() を実行します いくつかの追加ループ内で機能します。 C バージョンよりも効率は劣りますが、機能します。
おすすめ:
ループスリープにとどまります。理解しやすく、移植性が高く、ほとんどの場合ブロックされます。
sleep infinity それが示唆することを正確に実行し、猫の虐待なしで機能します.