使用nohup将命令在后台运行时,某些内容会出现在终端中。
cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error
我要将内容保存到文件中。 br />
#1 楼
Linux(和其他OS)中有两个主要输出流,标准输出(stdout)和标准错误(stderr)。错误消息(如您显示的错误消息)将打印为标准错误。传统的重定向操作符(command > file
)仅重定向标准输出,因此标准错误仍显示在终端上。要同时重定向stderr,您有几种选择:将stdout重定向到一个文件,将stderr重定向到另一个文件:
command > out 2>error
将stdout重定向到文件(
>out
),然后将stderr重定向到stdout(2>&1
):command >out 2>&1
将两个文件都重定向到一个文件(例如,并非所有的外壳程序都支持此文件,例如
bash
和zsh
不支持该文件,但sh
和ksh
不支持该文件):command &> out
有关各种控制和重定向运算符的更多信息,请参见此处。
评论
因此hashdeep -rXvvl -j 30 -k checksums.txt / mnt / app / >> result_hashdeep.txt 2> error_hashdeep.txt&或hashdeep -rXvvl -j 30 -k checksums.txt / mnt / app / >> result_hashdeep.txt 2>&1或hashdeep -rXvvl -j 30 -k checksums.txt / mnt / app /&> result_mixed.txt
–AndréM. Faria
15年5月18日在12:59
@AndréM.Faria是的。但是最后两个命令是等效的,它们会将错误和输出都发送到同一文件。
– terdon
15年5月18日在13:17
如您提供的链接中所示,我可以使用|&代替2>&1,它们等效,谢谢您的宝贵时间。
–AndréM. Faria
15年5月18日在13:38
@rohith我知道这是一个死灵,但是,您可以执行命令| sudo -S tee文件> / dev / null 2>&1
–寻宝者
18-10-11在21:58
我无法在&sh中工作,只能使用bash。 Cron用户要当心,请改用2>&1。
–迈克·麦凯(Mike McKay)
19年3月3日在11:41
#2 楼
首先要注意的是,有两种方法取决于您的目的和外壳,因此这需要对多个方面有一点了解。此外,某些命令(例如time
和strace
)默认情况下会将输出写入stderr,并且可能会或可能不会提供特定于该命令的重定向方法。重定向背后的基本理论是由shell产生的进程( (假设它是外部命令而不是内置的shell)是通过
fork()
和execve()
系统调用创建的,在此之前,另一个系统调用dup2()
在execve()
发生之前执行了必要的重定向。从这种意义上说,重定向是从父外壳继承的。 m&>n
和m>n.txt
通知外壳如何执行open()
和dup2()
系统调用(另请参见输入重定向的工作原理,重定向和管道之间的区别是什么以及输出重定向的含义和确切含义)外壳重定向
最典型的方法是在类似Bourne的外壳中通过
2>
进行操作,例如dash
(与/bin/sh
链接)和bash
;第一个是默认的且兼容POSIX的外壳,另一个是大多数用户用于交互式会话的外壳。它们的语法和功能不同,但是幸运的是,错误流重定向的工作原理相同(&>
非标准版本除外)。如果使用csh及其派生类,则stderr重定向在此处无法正常工作。回到
2>
部分。需要注意的两个关键事项:>
表示重定向运算符,我们打开文件,而2
整数表示stderr文件描述符;实际上,这正是POSIX Shell语言标准在2.7节中定义重定向的方式:[n]redir-op word
对于简单的
>
重定向,1
隐含了stdout
整数,即echo Hello World > /dev/null
与echo Hello World 1>/dev/null
相同。请注意,整数或重定向运算符不能用引号引起来,否则shell不能这样识别它们,而是将其视为文本的文字字符串。至于间距,重要的是整数要紧靠重定向运算符,但文件可以紧靠重定向运算符也可以不紧接,即command 2>/dev/null
和command 2> /dev/null
可以正常工作。 shell中典型命令的语法略为简化。
command [arg1] [arg2] 2> /dev/null
这里的窍门是重定向可以出现在任何地方。即
2> command [arg1]
和command 2> [arg1]
均有效。请注意,对于bash
shell,存在一种同时重定向stdout和stderr流的&>
方法,但同样-它是bash专用的,并且如果您正在争取脚本的可移植性,则可能不起作用。另请参见Ubuntu Wiki和&>和2>&1之间有什么区别。注意:
>
重定向操作符将截断文件并覆盖它(如果该文件存在)。 2>>
可用于将stderr
附加到文件中。 如果您可能会注意到,
>
仅用于一个命令。对于脚本,我们可以像在myscript.sh 2> /dev/null
中那样从外部重定向整个脚本的stderr流,也可以使用内置的exec。可以说,内置的exec可以重新交互整个Shell会话的流,无论是交互方式还是通过脚本。类似于#!/bin/sh
exec 2> ./my_log_file.txt
stat /etc/non_existing_file
在此示例中,日志文件应显示
stat: cannot stat '/etc/non_existing_file': No such file or directory
。 另一种方法是通过函数。正如kopciuszek在他的回答中指出的那样,我们可以编写具有附加的重定向的函数声明,即
some_function(){
command1
command2
} 2> my_log_file.txt
专门写到stderr的命令
默认情况下,诸如
time
和strace
之类的命令会将其输出写入stderr。对于time
命令,唯一可行的选择是重定向整个命令的输出,即time echo foo 2>&1 > file.txt
或者,如果您要重定向同步列表或子Shell,则可以分隔输出(如相关文章中所示):
{ time sleep 1 2> sleep.stderr ; } 2> time.txt
其他命令(例如
strace
或dialog
)提供了重定向stderr的方法。 strace
具有-o <filename.txt>
选项,该选项允许指定应在其中写入输出的文件名。还有一个选项可以为strace
看到的每个子进程编写一个文本文件。 dialog
命令将文本用户界面写入stdout但输出到stderr,因此,为了将其输出保存到变量(因为var=$(...)
和管道仅接收stderr),我们需要交换文件描述符result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);
但除此之外,还有
--output-fd
标志,我们也可以使用。还有命名管道的方法。我建议阅读有关dialog
命令的链接文章,以全面了解正在发生的事情。
评论
@terdon这是一个更具体的问题,它在Google搜索中正确显示了更具体的问题,这是一件好事。@nroose是的,它会不断显示,不会改变。但是,任何新的答案都应该针对更笼统的问题。