使用管道将两个参数传递给命令

gow*_*eon 27 bash shell-script pipe command-line-arguments bash-scripting

通常,我们只需要传递一个参数:

echo abc | cat
echo abc | cat some_file -
echo abc | cat - some_file
Run Code Online (Sandbox Code Playgroud)

有没有办法传递两个参数?就像是

{echo abc , echo xyz} | cat
cat `echo abc` `echo xyz`
Run Code Online (Sandbox Code Playgroud)

我可以先将两个结果存储在一个文件中

echo abc > file1
echo xyz > file2
cat file1 file2
Run Code Online (Sandbox Code Playgroud)

但是我可能会不小心覆盖一个文件,这是不行的。这是进入一个非交互式脚本。基本上,我需要一种方法来将两个任意命令的结果传递给cat而不写入文件。


更新:抱歉,该示例掩盖了问题。虽然{ echo abc ; echo xyz ; } | cat似乎确实有效,但输出是由于echos 而不是cat.

一个更好的例子是{ cut -f2 -d, file1; cut -f1 -d, file2; } | paste -d,它不能按预期工作。

file1:
a,b
c,d

file2:
1,2
3,4
Run Code Online (Sandbox Code Playgroud)

预期输出为:

b,1
d,3
Run Code Online (Sandbox Code Playgroud)

解决:

使用进程替换cat <(command1) <(command2)

或者,使用mkfifo以下方法制作命名管道:

mkfifo temp1
mkfifo temp2
command1 > temp1 &
command2 > temp2 &
cat temp1 temp2
Run Code Online (Sandbox Code Playgroud)

不太优雅,更冗长,但工作正常,只要您事先确保 temp1 和 temp2 不存在。

Ric*_*lka 19

我想你想要“进程替换” http://tldp.org/LDP/abs/html/process-sub.html。它也适用于 zsh,尽管它有更多选项并且语法可能不同。

/dev/fd/something为每个替换创建一个伪文件 ( )。它非常有用。该命令只能作为流读取,这意味着它不能与 fseek 来回切换。它需要将它作为字节流来读取,就像管道一样。

您的示例用作流程替换:

cat <(echo abc) <(echo xyz)
paste -d, <(cut -f2 -d, file1) <(cut -f1 -d, file2)
Run Code Online (Sandbox Code Playgroud)

把它想象成一个使用进程的工具,让它假装是一个没有任何临时文件的文件。

(来自我之前的回答