定界符和过程替换之间有什么区别?

定界符和过程替换之间有什么区别?

在这个答案中,解释了如何通过将交互程序的标准输入与定界符连接来使用定界符与交互式程序进行交互。

https://stackoverflow.com/questions/21130757/send-commands-to-socket-using-netcat

因为我想“啊文件!”我可以使用进程替换!

所以我尝试了:

nc -lvkp 8000 <(echo "test")

然后我得到了错误:

Ncat: Could not resolve hostname "/dev/fd/63

所以它是一个文件!但 netcat 不理解它(它确实用我在 中编写的普通文件来理解它/tmp/commands.txt)。我不太介意 netcat 不理解它。

我真正介意的是,如果我理解正确的话,我认为heredoc也是一个临时文件。但显然 netcat 明白这一点。所以这/dev/fd/63和定界符之间一定有区别。

那么区别是什么呢?

我认为部分原因是/dev/fd/63.它要么不是永久性的,要么dev/fd部分不同。然后我认为定界符不会保存在那里,而是保存在其他地方。

编辑:用echo "test",我的意思是“打印单词测试”。

答案1

here-document 是一个标准重定向,虽然进程替换不是标准的(因此并非所有 shell 都支持它们),它们也不是重定向。

明确的过程替换执行命令创建可以从特定路径名读取的输出,而此处文档创建一个文本文件立即重定向。此处文档可能可以通过写入临时文件来实现,但也可以通过写入命名管道或其他类似的东西来实现。

请注意,您的nc调用不会将进程替换的结果传递到 的标准输入流上nc,而是作为命令行上的文件名传递。要echo使用进程替换传递标准输入的输出,请使用

nc -lvkp 8000 < <( echo "test" )

请注意第一个如何<从进程替换产生的路径名进行重定向。

使用此处文档,您将编写

nc -lvkp 8000 <<'END'
test
END

请注意此处文档如何完成重定向,而不引用特定路径名。另请注意,我们如何不使用该echo命令来创建重定向文档的文本。

答案2

这里的文档是一个重定向。 shell 将文本保存在某处,然后将其重定向到命令的输入。 (这可能不是确切的机制,但对于思考系统来说已经足够了。)

进程替换提供连接到命令的输入或输出的路径里面过程替代。但是,它本身不会对除该命令之外的任何内容应用任何重定向。如果重定向符号(>in>(...)<in <(...))让您有不同的想法,只需认为它们适用于内部的任何内容 -> 指向进程替换适用于输入里面的命令,<指出同样适用于输出。他们不影响任何事情外部

所以,在:

nc 192.168.1.186 9760 <<END
command1
command2
END

nc的输入被重定向,但是在

nc -lvkp 8000 <(echo "test")

nc的输入是不是重定向。 (echo然而, 的输出通过管道传输到从进程替换中读取的任何内容。)nc只是得到一个额外的参数。

您需要自己应用该重定向:

nc -lvkp 8000 < <(echo "test")

答案3

这凸显了差异。 wc 在这两种情况下看到相同的数据。首先,它在命令行上获取一个参数(临时文件名)。在第二个例子中,文件名被 shell 重定向吃掉,wc 没有得到 arg,并且默认读取 stdin。

Paul--) wc <( echo one two three )
      1       3      14 /dev/fd/63
Paul--) wc < <( echo one two three )
      1       3      14
Paul--) 

答案4

我读过一些很好的答案,它们并不像我要写的那么简单,所以这里是:

  • 此处的 doc <<,连接到标准。
  • 处理替换<(...),连接到“文件”,然后替换文件名。

注意:当我们说文件时,我们是以 Unix 方式使用它的。不一定是磁盘上的文件。它可以是一个目录、命名管道、匿名管道、net-socket、unix-socket...在这种情况下,它将是一个(去匿名化:有一个文件名,仅对它所在的进程可见)连接到)匿名管道。

相关内容