And*_*ria 538 command-line redirect
使用 nohup 将命令在后台运行时,某些内容会出现在终端中。
cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error
Run Code Online (Sandbox Code Playgroud)
我想将该内容保存到文件中。
ter*_*don 914
Linux(和其他操作系统)中有两个主要的输出流,标准输出(stdout)和标准错误(stderr)。错误消息,就像你显示的那样,被打印为标准错误。经典重定向运算符 ( command > file) 仅重定向标准输出,因此终端上仍会显示标准错误。要重定向 stderr,您有几个选择:
将 stdout 重定向到一个文件,将 stderr 重定向到另一个文件:
command > out 2>error
Run Code Online (Sandbox Code Playgroud)将 stdout 重定向到文件 ( >out),然后将 stderr 重定向到 stdout ( 2>&1):
command >out 2>&1
Run Code Online (Sandbox Code Playgroud)既重定向到一个文件中(这是不是所有的炮弹支持,bash并zsh支持它,例如,但sh并ksh没有):
command &> out
Run Code Online (Sandbox Code Playgroud)有关各种控制和重定向运算符的更多信息,请参见此处。
Ser*_*nyy 28
首先要注意的是,根据您的目的和外壳,有几种方法,因此这需要对多个方面略有了解。此外,某些命令,如time和strace写入输出到默认标准错误,并且可以或可以不以该命令提供重定向特定的方法
重定向背后的基本理论是,一个由 shell 产生的进程(假设它是一个外部命令而不是 shell 内置的)是通过fork()和execve()系统调用创建的,在此之前,另一个系统调用dup2()会在execve()发生之前执行必要的重定向。从这个意义上说,重定向是从父 shell 继承的。在m&>n与m>n.txt通知有关如何执行壳open()和dup2()系统调用(另见如何输入重定向的作品,是什么重定向和管道之间的区别,以及什么在输出重定向确实与准确平均值)
最典型的,是通过2>在类似Bourne壳,如dash(其被链接到/bin/sh)和bash; 第一个是默认的和 POSIX 兼容的 shell,另一个是大多数用户用于交互式会话的。它们在语法和功能上有所不同,但幸运的是,错误流重定向的工作原理相同(&>非标准重定向除外)。在 csh 及其衍生产品的情况下,stderr 重定向在那里不太适用。
让我们回到2>部分。需要注意的两个关键事项:>表示重定向操作符,我们打开一个文件,2整数表示 stderr 文件描述符;事实上,这正是 shell 语言的 POSIX 标准在第 2.7 节中定义重定向的方式:
[n]redir-op word
Run Code Online (Sandbox Code Playgroud)
对于简单的>重定向,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
Run Code Online (Sandbox Code Playgroud)
这里的技巧是重定向可以出现在任何地方。这既2> command [arg1]和command 2> [arg1]有效。请注意,对于bashshell,存在&>同时重定向 stdout 和 stderr 流的方法,但同样 - 它是特定于 bash 的,如果您正在努力实现脚本的可移植性,它可能不起作用。另请参阅Ubuntu Wiki和&> 和 2>&1 之间的区别是什么。
注:该>重定向操作截断文件并将其覆盖,如果该文件存在。该2>>可用于附加stderr到文件中。
如果您可能注意到,>用于单个命令。对于脚本,我们可以像 in 一样从外部重定向整个脚本的 stderr 流,myscript.sh 2> /dev/null或者我们可以使用exec 内置。exec 内置函数可以为整个 shell 会话重新连接流,可以这么说,无论是交互方式还是通过脚本。就像是
#!/bin/sh
exec 2> ./my_log_file.txt
stat /etc/non_existing_file
Run Code Online (Sandbox Code Playgroud)
在此示例中,日志文件应显示stat: cannot stat '/etc/non_existing_file': No such file or directory.
还有一种方法是通过函数。正如kopciuszek在他的回答中指出的那样,我们可以编写带有已附加重定向的函数声明,即
some_function(){
command1
command2
} 2> my_log_file.txt
Run Code Online (Sandbox Code Playgroud)
默认情况下,诸如time和 之类的命令strace将其输出写入 stderr。在time命令的情况下,唯一可行的选择是重定向整个命令的输出,即
time echo foo 2>&1 > file.txt
Run Code Online (Sandbox Code Playgroud)
或者,如果您想分离输出(如相关帖子所示),可以重定向同步列表或子shell :
{ time sleep 1 2> sleep.stderr ; } 2> time.txt
Run Code Online (Sandbox Code Playgroud)
其他命令,例如strace或dialog提供重定向标准错误的方法。strace具有-o <filename.txt>允许指定应写入输出的文件名的选项。还有一个选项可以为strace看到的每个子进程编写一个文本文件。该dialog命令将文本用户界面写入标准输出但输出到标准错误,因此为了将其输出保存到变量(因为var=$(...)管道只接收标准错误)我们需要交换文件描述符
result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);
Run Code Online (Sandbox Code Playgroud)
但此外,还有--output-fd标志,我们也可以使用。还有命名管道的方法。我建议阅读有关该dialog命令的链接帖子,以全面描述正在发生的事情。
| 归档时间: |
|
| 查看次数: |
989443 次 |
| 最近记录: |