重定向到/ dev / null


144

我正在阅读一个示例bash shell脚本:

#!/bin/bash

# This script makes a backup of my home directory.

cd /home

# This creates the archive
tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1

# First remove the old bzip2 file.  Redirect errors because this generates some if the archive
# does not exist.  Then create a new compressed file.
rm /var/tmp/home_franky.tar.bz2 2> /dev/null
bzip2 /var/tmp/home_franky.tar

# Copy the file to another host - we have ssh keys for making this work without intervention.
scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1

# Create a timestamp in a logfile.
date >> /home/franky/log/home_backup.log
echo backup succeeded >> /home/franky/log/home_backup.log

我试图在这里了解“ / dev / null 2>&1”的用法。起初,我以为这个脚本使用/ dev / null来优雅地忽略错误,而又不会导致脚本崩溃(有点像用编程语言尝试捕获异常处理)。因为我看不到使用tar将目录压缩到tar文件中的方式,可能会导致任何类型的错误。


3
重定向到/dev/null不会阻止崩溃,但会清理stdout和stderr输出流。tar可能以多种方式导致错误。您可能没有写访问权限,文件可能已经存在,等等
。– Sparhawk

3
这只是避免不必要输出的一种技巧。至于tar为何会导致错误的原因:因为目标目录不存在,因为源目录不存在,因为您没有对目标的写访问权,或者对源tar没有读权限,因为它不在$ PATH中,因为tar崩溃(您永远不会知道),因为设备上没有空间,因为tar版本已更改并且现在需要不同的语法,因为磁盘导致了I / O错误。我相信您可以找到更多。
terdon

Answers:


223

不,这不会阻止脚本崩溃。如果在此tar过程中发生任何错误(例如:权限被拒绝,没有此类文件或目录,...),脚本仍将崩溃。

因为使用> /dev/null 2>&1会将您的所有命令输出(stdoutstderr)重定向到/dev/null,这意味着不会将任何输出打印到终端。

默认:

stdin  ==> fd 0
stdout ==> fd 1
stderr ==> fd 2

在脚本中,使用> /dev/null导致:

stdin  ==> fd 0
stdout ==> /dev/null
stderr ==> fd 2

然后2>&1导致:

stdin  ==> fd 0
stdout ==> /dev/null
stderr ==> stdout

3
据了解> /dev/null 2>&1,此命令导致stderr ==> stdout,因此stderr仍会打印到stdout?
曾伟石

11
可能不太重要,但这是什么fd
kev


7
为什么:CMD > /dev/null 2>&1工作但CMD 2>&1 > /dev/null仍然给我STDERR?
dbmikus

3
推荐:2>& 1在代码示例中使用,以强调数字和&符被视为重定向运算符的一部分。重定向到文件通常在>和之间有一个空格/path/to/file,重定向到文件描述符本质上是同一回事。
亨克·兰格维德

21

我试图在这里了解“> / dev / null 2>&1”的用法。

(请注意,我之前/dev/null在您的问题中添加了重定向。)

上面将把STDOUT和重定向STDERR/dev/null。它通过合并STDERRSTDOUT。(基本上,命令的所有输出都将重定向到null设备。)

...而不会导致脚本崩溃(类似于尝试捕获编程语言中的异常处理)。

它不是完全像a try/catch或其他任何东西。它只是使命令的任何形式的输出(包括错误)静音

因为我看不到使用tar将目录压缩到tar文件中的方式,可能会导致任何类型的错误。

出于多种原因,它可能导致错误,包括:

  • 您尝试存档的文件或您尝试写入的文件的权限不足
  • 缺少磁盘空间以创建档案

很好的解释。
Aditya Gupta

7

当您运行CMD> / dev / null 2>&1时

STDOUT重定向到/ dev / null,然后STDERR重定向到STDOUT的地址,该地址已设置为/ dev / null,因此STDOUT和STDERR都指向/ dev / null

相反,当您运行CMD 2>&1> / dev / null时

STDERR重定向到STDOUT的地址(此时是文件描述符1,或/ proc / self / fd / 1),然后STDOUT重定向到/ dev / null,但STDERR始终重定向到fd1!结果,STDOUT的正常输出被丢弃,但是来自STDERR的错误仍被写入控制台。


-2

Bash I / O重定向

清除问题的主要思路是:

重定向从右到左应用,这与英语使用者通常的阅读方式相反。


所以这段代码:

command > filename 2>&1

重定向stderrstdout 第一2>&1)和然后发送stdout(包括重定向stderr)至filename> filename)。这是ABSG的说明(第20章)

这段代码:

command >>/dev/null 2>&1

重定向stderrstdout/dev/null...这意味着到无处。发送到/dev/null的内容不会以任何方式保存,缓存或记忆。

他们只是被送到“ 无处 ”而被遗忘了。这是一种运行程序并确保其不会产生输出的方式,并且不会在命令行或日志文件中显示该程序。


我看到这种类型的问题相当多……主要是因为我已经多年没有编码了,所以不得不自己查一下。以下是来自ABSG的一些方便信息:

“重定向只是意味着从文件,命令,程序或脚本捕获输出,并将其作为输入发送到另一个文件,命令,程序或脚本。”

2>&1 
# Redirects stderr to stdout.

command >>filename 2>&1
# Appends both stdout and stderr
#+  to the file "filename" ...

ABSG:Advanced Bash脚本指南:上面第20章链接是指向开源tldp.org文档的I / O重定向页面的链接,该文档称为Mendel Cooper 的Advanced Bash脚本指南。它被列为“ shell脚本艺术的深入探索”,我绝对同意。这是一种了不起的资源,对各种疯狂的情况都有很多答案。

其他有价值的资源:Linux Documentation Project Guides页面的current / maintenance部分中有许多有价值的资源(采用html,pdf,text等便捷格式)。以下是一些我发现有用的信息:


1
不,重定向从左到右处理。在您的示例中,标准输出重定向到filename,然后标准错误重定向到标准输出当前要到达的任何地方filename。如果情况相反,则标准错误将在终端上终止,而仅将标准输出重定向到filename。另外,如果无法创建in command >file1 2>file2file2file1不会创建(无论file1file2实际是完全不同的路径名)。
库萨兰达
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.