Bashでは次を使用できます:cat <(echo "$FILECONTENT")
Bashは次の使用も許可します:while read i; do echo $i; done </etc/passwd
前の2つを組み合わせるために、これを使用できます:echo $FILECONTENT | while read i; do echo $i; done
最後の問題は、サブシェルを作成し、whileループの終了後に変数i
にアクセスできなくなることです。
私の質問は:
このようなことを達成する方法:while read i; do echo $i; done <(echo "$FILECONTENT")
または言い換えると:i
がwhileループで生き残ることをどのように確認できますか?
Whileステートメントを{}
で囲むことは承知していますが、これでは問題は解決しません(関数でwhileループを使用してi
変数を返すと想像してください)
Process Substitution の正しい表記は次のとおりです。
while read i; do echo $i; done < <(echo "$FILECONTENT")
ループで割り当てられたi
の最後の値は、ループの終了時に使用可能になります。別の方法は次のとおりです。
echo $FILECONTENT |
{
while read i; do echo $i; done
...do other things using $i here...
}
中括弧はI/Oグループ化操作であり、サブシェル自体は作成しません。このコンテキストでは、これらはパイプラインの一部であり、したがってサブシェルとして実行されますが、これは|
ではなく{ ... }
が原因です。あなたは質問でこれに言及します。私の知る限り、関数内でこれらの中から戻ることができます。
Bashは shopt
ビルトインも提供し、その多くのオプションの1つは次のとおりです。
lastpipe
設定され、ジョブ制御がアクティブでない場合、シェルは現在のシェル環境のバックグラウンドで実行されていないパイプラインの最後のコマンドを実行します。
したがって、スクリプトでこのようなを使用すると、変更されたsum
がループの後に使用可能になります。
FILECONTENT="12 Name
13 Number
14 Information"
shopt -s lastpipe # Comment this out to see the alternative behaviour
sum=0
echo "$FILECONTENT" |
while read number name; do ((sum+=$number)); done
echo $sum
これをコマンドラインで実行すると、通常、「ジョブコントロールがアクティブではありません」というファウルが発生します(つまり、コマンドラインではジョブコントロールがアクティブになります)。スクリプトを使用せずにこれをテストすると失敗しました。
また、 answer の Gareth Rees で示されているように、 here string を使用することもできます。
while read i; do echo $i; done <<< "$FILECONTENT"
これにはshopt
は必要ありません。それを使用してプロセスを保存できる場合があります。
Jonathan Lefflerが説明します 使用したいことを行う方法 process substitution ですが、別の可能性は here string を使用します。
while read i; do echo "$i"; done <<<"$FILECONTENT"
これによりプロセスが節約されます。