`test.sh&| test.sh`エラーが発生するのはなぜですか?

`test.sh&| test.sh`エラーが発生するのはなぜですか?

次の名前の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

おすすめ記事