6

ループがコマンドから行を読み取るループ内で bash エイリアスを作成したいと考えています。出力を 1 行ずつ読み取るには、出力を にパイプする必要があると思いますread。ただし、それを行うと、エイリアスは存在しません。

my に以下を含める場合.bashrc:

for x in a1 a2; do
    eval "alias $x='echo foo'"
done

echo -e "a3\na4" | while read x; do
    eval "alias $x='echo foo'"
done

エイリアスa1a2は存在しますが、a3and はありa4ません。これらの 2 つのループの違いは何ですか?

4

3 に答える 3

6

パイプ内の while ループはサブシェルで実行されます。できるよ:

while read x; do
    eval "alias $x='echo foo'"
done << EOF
a3
a4 
EOF
于 2012-08-28T17:15:12.447 に答える
5

問題はパイプラインです。形式のパイプラインではa | b | c、個々のコマンドab、およびcが個別のサブシェル [ ref ] で実行されます。これは、親の実行環境 (エイリアスを含む) のコピーと、独自の実行環境に対する変更を受け取ることを意味します。コピー (実行などによる) は、親 [ ref ]aliasには影響しません。

あなたの場合、次のように書くことでこれを修正できます:

while read x; do
    eval "alias $x='echo foo'"
done < <(echo -e "a3\na4")

これは引き続きecho -e "a3\na4"サブシェルで実行されますが、while-loop は通常/親実行環境で実行されます。

于 2012-08-28T17:14:22.620 に答える
3

bash 4.2 以降では、パイプの最後のコマンドがサブシェルで実行されlastpipeないようにするオプションを設定できます。これを機能させるには、ジョブ制御もオフ ( ) にする必要があります。set +m

shopt -s lastpipe
set +m
echo -e "a3\na4" | while read x; do
    alias $x='echo foo'
done
于 2012-08-28T17:28:20.707 に答える