次のような長いコマンドがあります。
$ command-outer "long command which references a file here: filename1, and another file reference here: filename2"
このファイルは他のコマンドの出力です。だから私はやっています:
$ command-outer "long ... "<(command-inner "again long params")"... "\
<(command-inner "again long params")" ..."
<()
読みやすくするために、長いコマンド呼び出しから名前のない/匿名の内部パイプ(パイプ付きパイプ)を抽出したいと思います。しかし、次のことができないようです。
RESULT_FILE_DESCRIPTOR1=<(command-inner ....)
RESULT_FILE_DESCRIPTOR1
引数リストで実際に使用すると、ファイル記述子がすでに閉じられている結果が発生しました。command-outer
command-outer
同じ回線で電話をかけたので、次のようになります。
RESULT_FILE_DESCRIPTOR1=<(command-inner ....) outer-command "long ... $RESULT_FILE_DESCRIPTOR1 ... "
空の結果RESULT_FILE_DESCRIPTOR1が返されますが、これは次の理由で驚くべきことではありません。
FOO=BAR echo $FOO
動作しません。
答え1
結果ではないコマンドにのみ名前を付けることができます。
param_set_1(){
input_command \
-lots \
-of \
-params
}
param_set_2(){
input_command \
-lots \
-of \
-other \
-params
}
command_outer -params <(param_set_1) <(param_set_2)
ファイル記述子を名前で参照することもできます。
param_set_1 | { param_set_2 | command_outer -params /dev/fd/3 -; } 3<&0
現在のシェル変数の結果が本当に欲しいならそしてファイル記述子ではパイプを避ける必要があります。その結果を親シェル変数に割り当てようとすると、コマンドの出力でパイプバッファを埋める危険性があり、読み取りプロセスによってパイプバッファが使い果たされる可能性があります。したがって、すべての操作を一度に実行し、ここにあるマニュアルを使用する必要があります。
unset fd3 fd4
{ command_outer -params /dev/fd/[34]
} 3<<FD3 4<<FD4
${fd3=$(param_set_1)}
FD3
${fd4=$(param_set_2)}
FD4
答え2
名前付きパイプを明示的に使用できます(プロセスの交換は詳細で名前付きパイプを使用すると思います)。
trap cleanup EXIT
cleanup() { rm -f "$inner1" "$inner2"; }
inner1=$(mktemp -u) && mkfifo "$inner1"
command-inner "again long params" > "$inner1" &
inner2=$(mktemp -u) && mkfifo "$inner2"
command-inner "again long params" > "$inner2" &
command-outer "long ... $inner1... $inner2 ..."