我需要将 stdout 和 stderr 记录到日志文件中,但只在屏幕上显示错误消息。我可以这样做:
cp -rpv a/* b 1> copyLog.txt 2> >(tee copyError.txt >&2)
我在网络上的某个地方找到的。
我只想知道这个>(tee copyError.txt >&2)
东西怎么称呼?我无法用谷歌搜索它,因为谷歌会忽略尖括号和圆括号等字符。
答案1
从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.
您可以通过按/
并输入搜索字符串来搜索联机帮助页,这是查找此类信息的好方法。当然,它确实要求您知道要在哪个联机帮助页中搜索:)
但您必须引用它(
,因为它在搜索时具有特殊含义。要在 bash 联机帮助页中查找相关部分,请输入/>\(
。
答案2
>(tee copyError.txt >&2)
实际上是几个不同的功能:
>(...)
称为“过程替代”。它创建了一个命名管道文件输入/dev/fd
和写入该文件将为括号中的进程提供输入。>
:通常,这称为“输出重定向”,允许您将标准输出 (>
或1>
) 或标准错误 (2>
) 发送到文件或进程。>&2
是输出重定向,但在这种情况下, 的输出tee
被发送到标准错误(这就是&2
标准&1
输出)如果没有
>
,括号 (()
) 将启动一个子 shell。运行括号中的命令将生成另一个 shell,该 shell 仅在这些命令运行时存在。如果您在子 shell 中声明一个变量,您可以看到它是如何工作的:$ foo='Tom';(foo='Dick'; echo "Sub: $foo"); echo "Orig: $foo" Sub: Dick Orig: Tom
正如您所看到的,
$foo
子 shell 中定义的 与父 shell 中定义的是分开的。