shell 特性 `>(tee copyError.txt >&2)` 的名称是什么?

der*_*imn 11 shell bash

我需要将 stdout 和 stderr 记录到日志文件中,但只在屏幕上显示错误消息。我可以这样做:

cp -rpv a/* b 1> copyLog.txt 2> >(tee copyError.txt >&2) 
Run Code Online (Sandbox Code Playgroud)

我在网上某处找到的。

我只想知道这个>(tee copyError.txt >&2)东西怎么叫?我不能用谷歌搜索它,因为谷歌忽略了尖括号和圆括号之类的字符..

Mar*_*ich 11

来自man bash

   Process Substitution
       Process substitution is supported  on  systems  that  support
       named  pipes  (FIFOs)  or  the  /dev/fd method of naming open
       files.  It takes the form of <(list) or >(list).  The process
       list  is  run with its input or output connected to a FIFO or
       some file in /dev/fd.  The name of this file is passed as  an
       argument  to  the current command as the result of the expan?
       sion.  If the >(list) form is used, writing to the file  will
       provide  input  for  list.   If the <(list) form is used, the
       file passed as an argument should be read to obtain the  out?
       put of list.
Run Code Online (Sandbox Code Playgroud)

您可以通过按搜索联机帮助页 /然后键入搜索字符串,这是查找此类信息的好方法。它当然要求您知道在哪个联机帮助页中进行搜索 :)

您必须引用(虽然,因为它在搜索时具有特殊含义。要在 bash 联机帮助页中查找相关部分,请键入/>\(.


ter*_*don 8

>(tee copyError.txt >&2) 其实就是几个不同的特点:

  • >(...)称为“过程替换”。它在其中创建一个命名管道文件/dev/fd,写入该文件将为括号中的进程提供输入。

  • >:通常,这称为“输出重定向”,它允许您将标准输出 (>1>) 或标准错误 ( 2>) 发送到文件或进程。 >&2输出重定向,但在这种情况下,输出tee被发送到标准错误(这是&2是,&1是标准输出)

  • 如果没有>,括号 ( ()) 将启动一个子 shell。括号中的运行命令将产生另一个 shell,只要这些命令正在运行,它就会存在。如果您在子 shell 中声明一个变量,您可以看到它是如何工作的:

    $ foo='Tom';(foo='Dick'; echo "Sub: $foo"); echo "Orig: $foo"
    Sub: Dick
    Orig: Tom
    
    Run Code Online (Sandbox Code Playgroud)

    如您所见,$foo在子shell 中定义的 与在父shell 中定义的不同。

  • 没有 `&gt;(...)` 不是重定向。`&gt;(...)` 扩展为文件名。如果你想_redirect_输出到那个,你需要`&gt; &gt;(...)`但是`&gt;(...)`更普遍地用于不能使用重定向的地方。OP的命令可以用传统的管道来实现,不需要在那里进行进程替换。 (4认同)
  • @chhh, `cmd 2&gt;&amp;1 &gt; 输出 | 开球错误 &gt;&amp;2` (3认同)