一 /dev/null
在类 Unix系统中, /dev/null,或称空设备,是一个特殊的设备文件,它丢弃一切写入其中的数据(但报告写入操作成功;若使用$?,会返回0,即命令执行成功)。
$?
最后运行的命令的结束代码(返回值)即执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误)
在程序员行话,尤其是Unix行话中,/dev/null 被称为位桶(bit bucket)或者黑洞(black hole)。空设备通常被用于丢弃不需要的输出流,或作为用于输入流的空文件。当你读它的时候,它会提供无限的空字符(NULL,ASCII NUL,0x00)。
其中的一个典型用法是cat $filename 会输出filename 对应的文件内容(输出到标准输出)
而使用 cat $filename > /dev/null 则不会得到任何信息,因为我们将本来该通过标准输出显示的文件信息重定向到了 /dev/null 中。
而使用 cat $filename 1>/dev/null 也会得到同样的效果,因为默认重定向的1就是标准输出。 (补充: 重定向的1 可以省略,意为标准输出,重定向的2 是标准错误输出)
我们使用 cat $filename 时如果filename 对应的文件不存在,系统肯定会报错:
"cat: filename: 没有那个文件或目录"
[root@zabbix-server ~]# ls
anaconda-ks.cfg a.txt
[root@zabbix-server ~]# cat aaa.txt
cat: aaa.txt: No such file or directory
如果我们不想看到错误输出呢?我们可以将错误输出写入到 2> 后面的空设备即 /dev/null 中。(2>/dev/null “>”号前后不能有空格)
[root@zabbix-server ~]# ls
anaconda-ks.cfg a.txt
[root@zabbix-server ~]# cat aaa.txt
cat: aaa.txt: No such file or directory
[root@zabbix-server ~]# cat aaa.txt 2>/dev/null
对比:
总结:
1 cat $filename 2>/dev/null 这条指令中 > 前面 2 是什么意思?
命令会有一个错误输出信息(包括错误提示,警告信息等) ,2> 会把这个错误输出信息写入到 2> 后面的文件中。 对于上面这条指令即为 将 cat $filename 命令的 错误输出信息 写入到 /dev/null 中。
2 重定向 1 (1可以省略不写),重定向的是标准输出stdout, 重定向 2 重定向的是标准错误输出stderr。
[root@zabbix-server ~]# cat a.txt
123456
[root@zabbix-server ~]# cat a.txt 2>/dev/null
123456
[root@zabbix-server ~]# cat a.txt >/dev/null
[root@zabbix-server ~]# cat a.txt 1>/dev/null
[root@zabbix-server ~]#
3 有时候,我并不想看到任何输出,我只想看到这条命令运行是不是正常,那么我们可以同时禁止标准输出stdout和标准错误输出stderr,比如:
cat $filename 2>/dev/null >/dev/null
如果 $filename 不存在,将不会有任何错误信息提示,
如果 $filename 存在,文件的内容将不会被打印到标准输出,
因此,上面的代码根本不会输出任何信息,当只想测试命令的退出码而不想有任何输出时非常有用(注意:使用 echo $? 查看上条命令的退出码:0为命令正常执行,1-255为有出错)
再比如:
[root@mysql-slave ~]# mysql -uroot -psdbrk -e "show slave status\G" 2>/dev/null >/dev/null
[root@mysql-slave ~]#
我遇到过的问题:
我们在使用mysql5.6及mysql5.7或更高版本时,当执行下面这条信息时会报警告:在命令行界面写密码不安全
[root@mysql-slave ~]# mysql -uroot -psdbrk -e "show slave status\G" | grep "Running" | grep -c "Yes"
mysql: [Warning] Using a password on the command line interface can be insecure.
1
如果使用zabbix监控mysql主从同步状态的话,将上面这条命令配置在zabbix-agentd.conf中,在zabbix-server端获取 其对应的item key值会报错:
zabbix-agentd.conf 配置 UserParameter
UserParameter=mysql.replication,mysql -uroot -psdbrk -e "show slave status\G" | grep "Running" | grep -c "Yes"
zabbix-server端 获取 mysql.replication的值时,报错
报错原因:这里报这种错误是因为返回的结果集中有字符串警告信息,而后台zabbix的item的是numeric所以存储不进去报错
如果改成下面这样的命令将警告信息写入到黑洞中就不会报错了:
UserParameter=mysql.replication,mysql -uroot -psdbrk -e "show slave status\G" 2>/dev/null | grep "Running" | grep -c "Yes"
zabbix-server端 获取mysql.replication的值时,不再报错
对比:
[root@mysql-slave ~]# mysql -uroot -psdbrk -e "show slave status\G" | grep "Running" | grep -c "Yes"
mysql: [Warning] Using a password on the command line interface can be insecure.
1
[root@mysql-slave ~]# mysql -uroot -psdbrk -e "show slave status\G" 2>/dev/null | grep "Running" | grep -c "Yes"
1
[root@mysql-slave ~]#
echo > a.txt 和 cat /dev/null >a.txt 的区别:
echo > a.txt
[root@zabbix-server ~]# cat a.txt
123456
[root@zabbix-server ~]# echo > a.txt
[root@zabbix-server ~]# cat a.txt
[root@zabbix-server ~]#
而 cat /dev/null > a.txt
[root@zabbix-server ~]# echo 123 > a.txt
[root@zabbix-server ~]# cat a.txt
123
[root@zabbix-server ~]# cat /dev/null > a.txt
[root@zabbix-server ~]# cat a.txt
[root@zabbix-server ~]#
二 /dev/zero
像 /dev/null 一样, /dev/zero也是一个伪文件。
/dev/null 它实际上产生连续不断的null的流(二进制的零流,而不是ASCII型的)。写入它的输出会丢失不见。
/dev/zero 主要的用处是用来创建一个指定长度,用于初始化的空文件,像临时交换文件,常和 dd 命令配合使用,见我的另一篇博客:linux 内存
三 shell中 0/1/2以及重定向的意思
shell中:
0表示标准输入(比如键盘输入)
1表示标准输出(输出到屏幕)
2表示标准错误输出(也是输出到屏幕)
> 默认为标准输出, 1> 通常可以省略成 > ,所以 >file 等价于 1>file
2>&1 将标准错误输出重定向到标准输入
&>file 将标准输出和标准错误输出都重定向输出到文件file中
>/dev/null 2>&1 错误返回值传递给1输出通道,&1表示1输出通道
2>/dev/null 1>&2 正确返回值传递给2输出通道,&2表示2输出通道
&>/dev/null 和 >/dev/null 2>&1 及 2>/dev/null 1>&2三者效果是等价的的
ls a.txt ab.txt >file.out 2>file.err 将 ls a.txt ab.txt 执行结果的标准输出重定向输出到file.err,将标准错误输出重定向输出到 file.err
eg:
有两个文件,a.txt中有内容,ab.txt文件不存在
[root@fastdfs ~]# cat a.txt
#!/bin/bash
# 创建一个16位的随机密码
for ((i=0;i<10;i++))
do
str1=`tr -dc '_A-Za-z0-9#@&%+' < /dev/urandom |head -c 15`
str2=$RANDOM
str=`echo $str1$str2|cut -c 3-18`
#echo $str1;echo $str2;
echo $str;
done
[root@fastdfs ~]# cat ab.txt
cat: ab.txt: No such file or directory
[root@fastdfs ~]#
则1:
[root@fastdfs ~]# cat a.txt >/dev/null
[root@fastdfs ~]# cat ab.txt >/dev/null
cat: ab.txt: No such file or directory
[root@fastdfs ~]#
[root@fastdfs ~]# cat a.txt 2>/dev/null
#!/bin/bash
# 创建一个16位的随机密码
for ((i=0;i<10;i++))
do
str1=`tr -dc '_A-Za-z0-9#@&%+' < /dev/urandom |head -c 15`
str2=$RANDOM
str=`echo $str1$str2|cut -c 3-18`
#echo $str1;echo $str2;
echo $str;
done
[root@fastdfs ~]# cat ab.txt 2>/dev/null
[root@fastdfs ~]#
[root@fastdfs ~]# cat a.txt &>/dev/null
[root@fastdfs ~]# cat ab.txt &>/dev/null
[root@fastdfs ~]#
[root@fastdfs ~]#
[root@fastdfs ~]# cat a.txt >/dev/null 2>&1
[root@fastdfs ~]# cat ab.txt >/dev/null 2>&1
[root@fastdfs ~]#
[root@fastdfs ~]# cat a.txt 2>/dev/null 1>&2
[root@fastdfs ~]# cat ab.txt 2>/dev/null 1>&2
[root@fastdfs ~]#
[root@fastdfs ~]#
则2:
[root@fastdfs ~]# ls a.txt
a.txt
[root@fastdfs ~]# ls ab.txt
ls: cannot access ab.txt: No such file or directory
[root@fastdfs ~]#
[root@fastdfs ~]# ls a.txt ab.txt //标准输出和标准错误输出都输出到屏幕
ls: cannot access ab.txt: No such file or directory
a.txt
[root@fastdfs ~]#
[root@fastdfs ~]# ls a.txt ab.txt >file.out 2>file.err //标准输出重定向输出到file.out,标准错误输出重定向输出到file.err
[root@fastdfs ~]#
[root@fastdfs ~]# cat file.out
a.txt
[root@fastdfs ~]# cat file.err
ls: cannot access ab.txt: No such file or directory
[root@fastdfs ~]#