可以在heredoc构造中的shell代码访问其父脚本的标准输入吗?

时间:2016-01-17 04:51:56

标签: shell pipe

我在shell脚本foo.sh中有以下结构:

(tr -d \\r|bash)<<:END

echo Hello World
# more lines of arbitrary bash code here

:END

据我所知,这牺牲了heredocced代码(称为“任意bash代码”)访问foo.sh标准输入的能力。换句话说,如果我说,例如

echo "something" | ./foo.sh

然后似乎没有办法允许heredocced bash代码访问字符串"something" - 相反,代码似乎表现得好像它的标准输入是一个空的,已关闭的文件。有没有办法解决这个问题?

[为了预防不可避免的“为什么你甚至......”的问题,首先使用这种结构的原因是它允许脚本运行,即使文件具有CRLF行结尾。实际上,该文件具有扩展名.bat,并且是一个双职能的跨平台可执行脚本,可以run from the command-line under either Windows or unix-like systems并用于引导更大的项目。为了便于在没有安装notepad.exe之类的新Windows系统上进行人类可读和可编辑,该文件具有Windows样式的行结尾。 ]

1 个答案:

答案 0 :(得分:4)

heredoc只是纯文本。通过将其转换为bash进程的标准输入,将其转换为命令脚本。当bash进程正在运行时,其标准输入已被重定向(在本例中为tr命令的输出),以及bash进程将用作其标准输入的内容。 (原谅冗余。)这是运行提供给shell标准输入的脚本的一般问题,并且与heredocs几乎没有关系。

这不是执行bash脚本的唯一方法。例如,您可以使用命名文件,即使名称为process substitution(假设您的驱动程序使用bash或其他支持该语法的shell。)这样做可以避免重定向标准输入的需要

bash <(tr -d \\r <<":EOF"
  read line
  echo Hello, "$line"
:EOF
)

如果这太深奥,您可以将heredoc复制到临时文件中,然后获取临时文件。