我有一个非常简单的初学者问题:
如何在shell脚本中将echo输出到标准输出和标准错误输出?
我知道可以将echo输出到标准错误输出,例如echo "foo" 1>&2
,但我需要同时输出到两个地方。
我尝试了一些谷歌搜索但没有起作用。
这应该可以解决问题
echo "foo" | tee /dev/stderr
/dev/stderr
。我认为大多数或所有现代类Unix系统都支持,但如果你担心古老的系统:line="foo"; echo "$line" ; echo "$line" 1>&2
。很容易将其包装在别名或函数中。 - Keith Thompson1>&2
中不需要1
,echo $line >&2
可以达到同样的效果。 - TWiStErRob/dev/stderr
。 - ACK_stoverflowecho foo | tee >(cat >&2)
即使不支持stderr,这也可以正常工作。
注意:如果您已经su到另一个帐户并且该帐户具有对tty的写权限,则Soren的答案将无法正常工作;但我的答案可以。
sh: Syntax error: "(" unexpected (expecting word)
。 - zezollo另一个解决方案,可能仅适用于Linux内核(及其/proc/
文件系统),但不需要bash:
echo foo | tee /proc/$$/fd/2
在这里,$$
包含正在运行的进程的 PID,而 /proc/some_pid/fd/2
将指向进程 some_pid
的文件描述符号 2。我们只是指示 tee
直接写入标准错误输出(编号为 2
)的文件描述符号,该标准错误输出属于由其 PID $$
标识的 shell 进程。
Tee 还输出到其标准输出,该输出未被重定向并最终出现在 stdout
(fd 1
) 上。
我也同意对问题的评论:正如链接的答案所示,可以创建一个指向我们的stderr
文件描述符的FIFO,然后使用tee
将其写入:
mkfifo /tmp/temp_fifo_file # this named fifo will appear in the /tmp directory
(cat /tmp/temp_fifo_file >&2 &) # Background `cat` process: read the fifo and echo to stderr
echo foo | tee /tmp/temp_fifo_file
rm /tmp/temp_fifo_file # cleanup
关于上面的两点说明:当收到EOF时,cat将关闭fifo并退出,因此它只能工作一次。我使用括号(子shell)来隐藏作业控制消息,但是它也可以不用。
为了避免关闭管道,它可以被打开为读写(确保阅读链接的警告,可能最好将exec放在与cat相同的子shell中,但这使得关闭文件描述符更加困难):
mkfifo /tmp/temp_fifo_file # this named fifo will appear in the /tmp directory
exec 3<>/tmp/temp_fifo_file # Open fifo as fd 3
(cat 0<&3 1>&2 & ) # stays in the background, cat reads fd 3 and outputs to stderr
echo foo | tee /tmp/temp_fifo_file
# Cleanup:
exec 3<&- # Close fd 3, this will terminate background job
rm /tmp/temp_fifo_file # remove fifo
(cat 0<&3 1>&2 & )
中,0和1可以省略,因为它们分别代表默认的标准输入和输出。
cat >&2
,答案仍然有效。 - Nemo