14

編集:

以下の私のコメント sed 's@^@ @' <(f1)は正しくありませ$BASH_SUBSHELLんが、私たちがローンチと同じレベルにいることを示していますが、変数はメインスクリプトで失われています。代わりにテストしたGordonsの回答に基づいてf1 > >(sed 's@^@ @')おり、それは正しく機能しているようです。それでも、最初のフォームでは BASH_SUBSHELL を 0 ではなく 1 にすべきではないでしょうか?


この小さなテストを検討してください

#!/bin/bash
declare -i i=0
function f1()
{
  let i++
  echo "In f1, SUBSHELL: $BASH_SUBSHELL, i=$i" >&2
}

f1
f1 | sed 's@^@     @'

echo "at end, i=$i"

次の出力で:

In f1, SUBSHELL: 0, i=1
In f1, SUBSHELL: 1, i=2
at end, i=1

(の目的は、sed何かへのパイプを持つことだけです。f1 は stderr に出力されるため、何かを行うとは思わないでください)

関数 f1 は、現在の BASH_SUBSHELL と i の現在の値をログに記録します

スクリプトの最後に が表示される理由はわかっていますi=1。これは、2 番目の呼び出しがサブシェルで行われ、サブシェル 1 の i の値が失われたためです。

私が知らないのは、パイプの左側が現在のシェルで実行されなかった理由です

これを回避できると思ったのですsed 's@^@ @' <(f1) が、左側がメインスクリプトと同じレベルにない理由を知りたいです

4

2 に答える 2

26

bash の man ページから: 「パイプライン内の各コマンドは、個別のプロセスとして (つまり、サブシェル内で) 実行されます。」現在のシェルでパイプラインの 1 つのコンポーネントを実行することは可能だと思います(つまり、最初、最後、または中間の 1つなど)。スクリプトを次のように変更した場合:

#!/bin/bash
declare -i i=0
function f1()
{
    let i++
    echo "In f1, SUBSHELL: $BASH_SUBSHELL, i=$i" >&2
}

f1
f1 | f1 | f1

echo "at end, i=$i"

それは印刷します:

In f1, SUBSHELL: 0, i=1
In f1, SUBSHELL: 1, i=2
In f1, SUBSHELL: 1, i=2
In f1, SUBSHELL: 1, i=2
at end, i=1

パイプラインでの f1 の 3 つの呼び出しはすべてサブシェルで実行されるためです。

于 2011-04-22T22:59:37.437 に答える
-1

誰かが気になる場合の非常に簡潔な例を次に示します。

cd / && cd /tmp/ | pwd  ; pwd
/
/

または :

cd / && cd /tmp/ | cd /var/  ; pwd
/

はい、このページがすべてを物語っています

http://linux.die.net/man/1/bash#パイプライン内の各コマンドは、個別のプロセスとして (つまり、サブシェル内で) 実行されます。

于 2014-02-26T22:26:13.303 に答える