有没有一种方法可以让标准输入“跳过”进程?例如,在以下命令中,
cat file | ssh host 'mkdir -p /some/directory && cat > /some/directory/file'
这会将标准输入从第一个发送cat
到第二个mkdir
,而第二个cat
将不会收到任何标准输入。我希望第一个的标准cat
输出跳过mkdir
并仅发送到第二个cat
。我知道你可以运行类似的东西:
cat file | ssh host 'cat > /tmp/file2 ; mkdir -p /some/directory && mv /tmp/file2 /some/directory/'
仅当复制文件或
cat file | ssh host 'tee >(mkdir -p /some/directory) >/some/directory/file'
但这只是因为该mkdir
命令不使用标准输入才有效。是否有一个命令可以执行复制此功能的命令?就像是:
cat file | ssh host 'stdinhop mkdir -p /some/directory | cat > /some/directory/file'
wherestdinhop
不会将其标准输入发送到 mkdir,但会将其重定向到标准输出,以便第二只猫可以读取它?
答案1
您可以从以下位置重定向第一个命令的标准输入/dev/null
:
anthony@Watt:~$ echo -e 'hello\nworld' | ssh localhost 'cat < /dev/null && cat -n'
1 hello
2 world
这些行已编号,因此第二个得到 cat
了它们。
如果在那里不使用 ssh,则可以使用子 shell:echo -e 'hello\nworld' | ( cat < /dev/null && cat -n )
答案2
事实上,你想要的已经发生了。当然mkdir
不是你的问题——它stdin
无论如何也不会读取。该管道由 - 的所有子级继承为标准输入,ssh
除非您获得像ssh -t
.
除此之外,问题在于运行这些命令的 shell 是ssh
的子级之一 - 它的部分工作是为其运行的每个命令组打开 0,1,2 。那么,您的输入就会在随机播放中丢失,因为它位于一个公共描述符上 - shell 为其每个子级重新打开的描述符相同。
因此,我认为最简单的是,您可以将输入移动到除这三个默认值之一之外的描述符。例如,以下内容对我有用:
echo hey there >file
cat file | ssh mikeserv@localhost '
exec 3<&0
mkdir -p .
echo ho there
cat <&3'
如果我运行上面的内容,它会打印:
ho there
hey there
您可能还会发现-W
选项中有一些实用程序ssh
。man ssh
说:
-W
主持人 :港口- 请求将客户端上的标准输入和输出转发到主持人在港口通过安全通道。意味着-N
、-T
、ExitOnForwardFailure
和ClearAllForwardings
。仅适用于协议版本 2