在使用 nohup 放置命令在后台运行时,一些内容出现在终端中。
cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error
我想将该内容保存到文件中。
在使用 nohup 放置命令在后台运行时,一些内容出现在终端中。
cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error
我想将该内容保存到文件中。
Linux(和其他操作系统)中有两个主要输出流,标准输出 (stdout) 和标准错误 (stderr)。错误消息,就像您显示的那样,被打印到标准错误。经典的重定向运算符 (
command > file
) 只重定向标准输出,所以标准错误仍然显示在终端上。要同时重定向 stderr,您有几个选择:将 stdout 重定向到一个文件,将 stderr 重定向到另一个文件:
将 stdout 重定向到文件 (
>out
),然后将 stderr 重定向到 stdout (2>&1
):将两者都重定向到一个文件(这不是所有 shell 都支持的
bash
,zsh
例如支持它,但sh
不ksh
支持):有关各种控制和重定向运算符的更多信息,请参见此处。
首先要注意的是,根据您的目的和外壳,有几种方法,因此这需要对多个方面有轻微的了解。此外,某些命令(例如默认情况
time
下strace
将输出写入 stderr)可能会或可能不会提供特定于该命令的重定向方法重定向背后的基本理论是,由 shell 生成的进程(假设它是一个外部命令而不是内置的 shell)是通过
fork()
和execve()
系统调用创建的,并且在此之前另一个系统调用会在发生dup2()
之前执行必要的重定向execve()
。从这个意义上说,重定向是从父 shell 继承的。并通知 shell 如何执行m&>n
和系统调用(另请参阅输入重定向的工作原理、重定向和管道的区别以及输出重定向中 & 的确切含义)m>n.txt
open()
dup2()
外壳重定向
最典型的是通过
2>
类似Bourne 的外壳,例如dash
(符号链接到/bin/sh
)和bash
;第一个是默认的和 POSIX 兼容的 shell,另一个是大多数用户用于交互式会话的。它们在语法和功能上有所不同,但幸运的是,错误流重定向的工作原理相同(&>
非标准重定向除外)。对于 csh 及其派生物,stderr 重定向在那里不太有效。让我们回到
2>
原点。需要注意的两个关键事项:>
表示重定向运算符,我们在其中打开文件,2
整数代表 stderr 文件描述符;事实上,这正是 POSIX 标准的 shell 语言在2.7 节中定义重定向的方式:对于简单
>
的重定向,1
整数隐含为stdout
,即echo Hello World > /dev/null
与 相同echo Hello World 1>/dev/null
。请注意,不能引用整数或重定向运算符,否则 shell 无法识别它们,而是将其视为文字字符串。至于间距,重要的是整数紧挨着重定向运算符,但文件可以紧挨着重定向运算符,也可以不紧挨着,即command 2>/dev/null
andcommand 2> /dev/null
会工作得很好。shell 中典型命令的稍微简化的语法是
这里的技巧是重定向可以出现在任何地方。这两者
2> command [arg1]
都是command 2> [arg1]
有效的。请注意,对于bash
shell,存在&>
同时重定向 stdout 和 stderr 流的方法,但同样 - 它是特定于 bash 的,如果您正在努力实现脚本的可移植性,它可能不起作用。另请参阅Ubuntu Wiki和&> 与 2>&1 之间的区别。注意:重定向
>
运算符截断文件并覆盖它(如果文件存在)。可2>>
用于附加stderr
到文件。如果您可能注意到了,
>
是针对一个命令的。对于脚本,我们可以从外部重定向整个脚本的 stderr 流,myscript.sh 2> /dev/null
或者我们可以使用内置的 exec。exec 内置有能力为整个 shell 会话重新连接流,可以说,无论是交互方式还是通过脚本。就像是在此示例中,日志文件应显示
stat: cannot stat '/etc/non_existing_file': No such file or directory
.还有一种方法是通过函数。正如kopciuszek在他的回答中指出的那样,我们可以编写带有已附加重定向的函数声明,即
专门写入 stderr 的命令
默认情况下,诸如
time
和之类的命令strace
会将其输出写入 stderr。在time
命令的情况下,唯一可行的选择是重定向整个命令的输出,即或者,如果您想分离输出,可以重定向同步列表或子 shell(如相关帖子所示):
其他命令,例如
strace
ordialog
提供重定向 stderr 的方法。strace
具有-o <filename.txt>
允许指定应写入输出的文件名的选项。还有一个选项可以为每个strace
看到的子进程编写一个文本文件。该dialog
命令将文本用户界面写入 stdout 但输出到 stderr,因此为了将其输出保存到变量(因为var=$(...)
管道只接收 stderr)我们需要交换文件描述符但除此之外,还有
--output-fd
我们也可以使用的标志。还有命名管道的方法。我建议阅读有关该dialog
命令的链接文章,以全面了解正在发生的事情。