您可以使用here-doc和。为其提供有效的,对POSIX友好的通用收集器模型。
. 8<<-\IOHERE /proc/self/fd/8
command
…
fn() { declaration ; } <<WHATEVER
# though a nested heredoc might be finicky
# about stdin depending on shell
WHATEVER
cat -u ./stdout | ./works.as >> expect.ed
IOHERE
当您打开heredoc时,您会用IOHERE输入令牌向外壳发出信号,表示该外壳应将其输入重定向到您指定的文件描述符,直到遇到限制符令牌的另一端为止。我环顾四周,但没有看到如上所示与heredoc运算符结合使用重定向fd号码的许多示例,尽管在POSIX基本shell命令指南中明确指定了它的用法。大多数人只是将其指向stdin并进行射击,但是我发现以这种方式采购脚本小程序可以使stdin不受限制,并且组成应用程序可以避免抱怨阻塞的I / O路径。
Heredoc的内容将流式传输到您指定的文件描述符,然后依次将其解释为shell代码并由。内置的,但并非没有指定的特定路径。。如果/ proc / self路径给您带来麻烦,请尝试/ dev / fd / n或/ proc / $$。顺便说一下,这种方法也适用于管道:
cat ./*.sh | . /dev/stdin
至少看起来像它一样不明智。当然,您可以使用sh进行相同的操作,但是。的目的是在当前的shell环境中执行,这可能是您想要的,并且,取决于您的shell,使用heredoc的可能性要大于使用thisdoc的可能性。使用标准的匿名管道。
无论如何,正如您可能已经注意到的那样,我仍然没有回答您的问题。但是,如果您考虑一下,以Heredoc将所有代码流式传输到.in的相同方式,它还为您提供了一个简单,简单的方法:
. 5<<EOIN /dev/fd/5 |\
tee -a ./log.file | cat -u >$(tty)
script
…
more script
EOIN
因此,您在heredoc中执行的任何代码中的所有终端标准输出都是从中输出的。当然,可以很容易地从一根管子上拉开。我之所以加入无缓冲的cat调用,是因为我不清楚当前的stdout方向,但是它可能是多余的(几乎可以肯定是写的那样),并且管道可能会在tee处结束。
您可能还会在第二个示例中质疑缺少的反斜杠引号。在您进入之前,这部分很重要,需要先了解一下,并且可能会给您一些关于如何使用它的想法。带引号的heredoc限制器(到目前为止,我们已经使用IOHERE和EOIN,而第一个带反斜杠的引号,尽管“单引号”或“双引号”具有相同的作用)将禁止外壳程序在shell上执行任何参数扩展内容,但未引用限制符将使其内容易于扩展。当您的Heredoc是时的结果。引人注目的是:
. 3<<HD ${fdpath}/3
: \${vars=$(printf '${var%s=$((%s*2))},' `seq 1 100`)}
HD
echo $vars
> 4,8,12…
echo $var1 $var51
> 4 104
因为我没有引用Heredoc限制器,所以在将结果读入文件之前,shell会在读取内容时扩展内容。执行。这实质上导致命令被解析两次-无论如何都是可扩展的。因为我用反斜杠引用了$ vars参数扩展,所以外壳程序在第一次通过时就忽略了它的声明,而只去除了反斜杠,因此当时,整个printf扩展的内容都可以用null求值。在第二遍获得脚本。
该功能基本上正是危险的eval shell内置程序可以提供的功能,即使在引证文件中引用比使用eval更容易处理,并且同样具有危险性。除非您仔细计划,否则最好还是习惯地引用“ EOF”限制器。只是说。
编辑:嗯,我回头看这个,以为这有点过分了。如果您需要做的只是将多个输出连接到一个管道中,那么最简单的方法就是使用:
{ or ( command ) list ; } | tee -a ea.sy >>pea.sy
curlies将尝试在当前shell中运行内容,而parens会自动分出。不过,任何人都可以告诉您,至少在我看来,。Heredoc解决方案是更有价值的信息,尤其是如果您想了解Shell的实际工作方式时。
玩得开心!