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
それが示唆することを正確に実行し、猫の虐待なしで機能します.