次の名前のbashスクリプトがありますtest.sh
。
#!/bin/bash
while :
do
echo xxx
sleep 1
done
./test.sh & | ./test.sh
なぜ私にエラーが発生するのかわかりません:-bash: syntax error near unexpected token |'
、while./test.sh | ./test.sh
と./test.sh | ./test.sh &
動作します。
答え1
シェルは単にこれを許可しません文法:
%start complete_command %% complete_command : list separator | list ; list : list separator_op and_or | and_or ; ... pipe_sequence : command | pipe_sequence '|' linebreak command ; ... separator_op : '&' | ';' ;
リストを終了する方法&
と;
リストはComplete_commandの一部にすぎず、他の本番の一部ではないことに注意してください。
{ foo & }
これは意味的に同様の構文に過ぎませんfoo &
(括弧とは異なり、中括弧はコマンドをグループ化するためにのみ使用され、それ自体はサブシェルやいかなる種類のスコープも生成しません)。意味的に渡す構文{ foo & } | bar
に似ています。foo & | bar
したがって、あなたの例の解決策は次のとおりです。
{ ./test.sh & } | ./test.sh
対話型シェルで実行している場合は、&
次の点に注意してください。いいえ作る背景作業ただし、パイプの右側は常にサブシェルで実行され、サブシェルのコマンドはジョブ制御が無効になっているため、コマンドは非同期でのみ実行されます。
これは次のようになります。
(sleep 3600 &)
サブシェルの非同期リスト(終了したコマンドを含む&
)が実行されると、stdinはリダイレクトされ、/dev/null
合計SIGINT
信号SIGQUIT
は無視されます。バックグラウンドで実行され続けますが、通常のジョブと同様に、theyなどを使用してfg
前景にインポートすることはできません。disown
また、サービスが停止または終了したときに通知されません。
スクリプトでは、ジョブ制御を無効にした状態でスクリプトが実行されるため、これには全く違いはありません。
しかし、パイプを介して背景を出力するには働くフロントに行く働く中インタラクティブシェルで私が考えることができる唯一のポータブルソリューションは、名前付きパイプを使用することです。
$ mkfifo fifo
$ command | filter1 > fifo & # this is the background job
$ < fifo sed 10q | filter2 # this is the foreground job