标准输入“跳过”进程?

标准输入“跳过”进程?

有没有一种方法可以让标准输入“跳过”进程?例如,在以下命令中,

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选项中有一些实用程序sshman ssh说:

  • -W 主持人 :港口- 请求将客户端上的标准输入和输出转发到主持人港口通过安全通道。意味着-N-TExitOnForwardFailureClearAllForwardings仅适用于协议版本 2

相关内容