したがって、最近の動作を停止したexec行でプロセス置換を使用するbashコマンドがあります。これは次の例にまとめられています。
script.shの内容:
#!/bin/bash
ls -l "$1" >/tmp/out
echo "SUCCESS" > "$1"
これはうまくいきますlog
。 「SUCCESS」を次の場所に入れてください。
rm -f log; ./script.sh >(cat >log)
また、以下を使用して機能しますtail
。
rm -f log; ./script.sh >(tail >log)
exec
作品と一緒に使用cat
:
rm -f log; exec ./script.sh >(cat >log)
しかし…exec
そしてtail
実際にいいえ働く:
rm -f log; exec ./script.sh >(tail >log)
すべての場合において、以下のように/tmp/outの内容が良好に見えます。
l-wx------ 1 user user 64 Oct 14 10:55 /dev/fd/63 -> pipe:[158518]
cat
うまくいきますが、うまくいかないのはなぜtail
ですかhead
?これは過去のある時点で機能しました。これはbash関数の変更かバグ回帰ですか..?
bash --version: GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
答え1
したがって、交換プロセスを使用すると、strace
カーネルがtail
。head
簡単な回避策は、nohup
代替項目を追加することです。
rm -fログ; exec ./script.sh >(nohup tail >log)
私はexecがなぜ失敗するのか理解していると思います。 IIUC、>(tail> log)は現在のプロセスの子プロセスを作成しますbash
。ただし、execを使用すると、今になりますscript.sh
。 script.shが終了すると、カーネルはそれをすべてのSIGHUP
子プロセスに送信します。
これがなぜ機能するのかはまだわかりません。最新のカーネルバージョンでは、SIGHUPをより迅速かつ積極的に送信できます。