将进程替换的文件描述符放入变量中

hbo*_*ert 4 bash pipe shell-script process-substitution

我有很长的命令大致是这样的:

$ command-outer "long command which references a file here: filename1, and another file reference here: filename2"
Run Code Online (Sandbox Code Playgroud)

这些文件是另一个命令的输出。所以我在做:

$ command-outer "long ... "<(command-inner "again long params")"...  "\
  <(command-inner "again long params")" ..."
Run Code Online (Sandbox Code Playgroud)

为了可读性,我想<()从长命令调用中提取内部未命名/匿名管道(带有 的管道)。但是我似乎不能这样做;执行以下操作:

RESULT_FILE_DESCRIPTOR1=<(command-inner ....)
Run Code Online (Sandbox Code Playgroud)

当我RESULT_FILE_DESCRIPTOR1在 params 列表中实际使用时,导致文件描述符已经关闭command-outer

command-outer在同一行调用,因此:

    RESULT_FILE_DESCRIPTOR1=<(command-inner ....) outer-command "long ... $RESULT_FILE_DESCRIPTOR1 ... "
Run Code Online (Sandbox Code Playgroud)

返回一个空结果 RESULT_FILE_DESCRIPTOR1,这并不奇怪,因为:

FOO=BAR echo $FOO
Run Code Online (Sandbox Code Playgroud)

也不起作用。

mik*_*erv 9

您可以只命名命令,而不是命名结果。

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)
Run Code Online (Sandbox Code Playgroud)

您还可以经常按名称引用文件描述符。

param_set_1 | { param_set_2 | command_outer -params /dev/fd/3 -; } 3<&0
Run Code Online (Sandbox Code Playgroud)

如果您真的希望在当前外壳变量文件描述符中获得结果,那么您应该避开管道。您冒着用命令的输出填充管道缓冲区的风险,同时尝试在管道缓冲区被读取过程耗尽之前将这些结果分配给父壳变量,并且......好吧,这并不漂亮。因此,您应该一口气完成所有操作,并使用此处的文档。

unset fd3 fd4
{   command_outer -params /dev/fd/[34]
}   3<<FD3 4<<FD4
${fd3=$(param_set_1)}
FD3
${fd4=$(param_set_2)}
FD4
Run Code Online (Sandbox Code Playgroud)