2018-07-16 20:15:36 u014229282 阅读数 273
  • 马哥Linux教程-Linux操作系统基础由浅入深全面讲解1

    本课程为全新马哥Linux全套系列课程之一--Linux基础入门和架构了解,从Linux起源,Linux架构和Linux形成历史开始逐步讲解,让你彻彻底底了解Linux的诞生,之后介绍了Linux相关文化和核心组成结构,以及Linux常用命令和基本用法,课程由浅入深,讲授方法受到98%学员一致好评!

    19684 人正在学习 去看看 马永亮

背景

我们在Linux下经常会碰到nohup command>/dev/null 2>&1 &这样形式的命令。首先我们把这条命令大概分解下首先就是一个nohup表示当前用户和系统的回话下的进城忽略响应HUP消息。&是把该命令以后台的job的形式运行。那么就剩下command>/dev/null 2>&1,command>/dev/null较好理解,/dev/null表示一个空设备,就是说吧command的执行结果重定向到空设备中,说白了就是不显示任何信息。那么2>&1又是什么含义?

解释2>&1

command>/dev/null 2>&1

几个基本符号及其含义

  • /dev/null 表示空设备文件
  • 0 表示stdin标准输入
  • 1 表示stdout标准输出
  • 2 表示stderr标准错误
  • nohup 表示不挂断地运行命令
    无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。
    如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。
    如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。
    该命令一般结合 nohup command & 来使用,表示后台运行


从command>/dev/null说起

其实这条命令是一个缩写版,对于一个重定向命令,肯定是a > b这种形式,那么command > /dev/null难道是command充当a的角色,/dev/null充当b的角色。这样看起来比较合理,其实一条命令肯定是充当不了a,肯定是command执行产生的输出来充当a,其实就是标准输出stdout。所以command > /dev/null相当于执行了command 1 > /dev/null。执行command产生了标准输出stdout(用1表示),重定向到/dev/null的设备文件中。

说说2>&1

通过上面command > /dev/null等价于command 1 > /dev/null,那么对于2>&1也就好理解了,2就是标准错误,1是标准输出,那么这条命令不就是相当于把标准错误重定向到标准输出么。等等是&1而不是1,这里&是什么?这里&相当于等效于标准输出。这里有点不好理解,先看下面。

command>a 2>a 与 command>a 2>&1的区别

通过上面的分析,对于command>a 2>&1这条命令,等价于command 1>a 2>&1可以理解为执行command产生的标准输入重定向到文件a中,标准错误也重定向到文件a中。那么是否就说command 1>a 2>&1等价于command 1>a 2>a呢。其实不是,command 1>a 2>&1与command 1>a 2>a还是有区别的,区别就在于前者只打开一次文件a,后者会打开文件两次,并导致stdout被stderr覆盖。&1的含义就可以理解为用标准输出的引用,引用的就是重定向标准输出产生打开的a。从IO效率上来讲,command 1>a 2>&1比command 1>a 2>a的效率更高。

示例

来个shel

//test.sh
#!/bin/sh
t
date

chmod +x test.sh为test.sh增加执行权限。这里我们弄了两条命令,其中t指令并不存在,执行会报错,会输出到stderr。date能正常执行,执行会输出当前时间,会输出到stdout。

执行./test.sh > res1.log结果为

我们发现stderr并没有被重定向到res1.log中,stderr被打印到了屏幕上。这也进一步证明了上面说的./test.sh > res1.log等价于./test.sh 1>res1.log

执行./test.sh>res2.log 2>&1结果为

这次我们发现stdout和stderr都被重定向到了res2.log中了。上面我们未对stderr也就是2说明如何输出,stderr就输出到了屏 幕上,这里我们不仅对stdout进行说明,重定向到res2.log中,对标准错误也进行了说明,让其重定向到res2.log的引用即 res2.log的文件描述符中。

思考

为何2>&1要写在command>1的后面,直接用2可以么。比如ls 2>a。其实这种用法也是可以的,ls命令列出当前的目录,用stdout(1)表示,由于这个时候没有stderr(2),这个时候执行ls 2>a也会正常产生一个a的文件,但是a的文件中是空的,因为这时候执行ls并没有产生stderr(2)。

本文章来源:https://github.com/Zeb-D/my-review

2019-09-23 16:12:06 Java_supermanNO1 阅读数 100
  • 马哥Linux教程-Linux操作系统基础由浅入深全面讲解1

    本课程为全新马哥Linux全套系列课程之一--Linux基础入门和架构了解,从Linux起源,Linux架构和Linux形成历史开始逐步讲解,让你彻彻底底了解Linux的诞生,之后介绍了Linux相关文化和核心组成结构,以及Linux常用命令和基本用法,课程由浅入深,讲授方法受到98%学员一致好评!

    19684 人正在学习 去看看 马永亮

点关注,不迷路;持续更新Java架构相关技术及资讯热文!!!

我们在Linux下经常会碰到

nohup command>/dev/null 2>&1 &

这样形式的命令。

  1. 首先我们把这条命令大概分解下首先就是一个nohup表示当前用户和系统的回话下的进城忽略响应HUP消息;
  2. &是把该命令以后台的job的形式运行;
  3. 那么就剩下command>/dev/null 2>&1,command>/dev/null较好理解,/dev/null表示一个空设备,就是说吧command的执行结果重定向到空设备中,说白了就是不显示任何信息;
  4. 最后,2>&1又是什么含义?

2>&1 几个基本符号及其含义

  • /dev/null 表示空设备文件
  • 0 表示stdin标准输入
  • 1 表示stdout标准输出
  • 2 表示stderr标准错误

分析 2>&1

对于2>&1的理解,2就是标准错误,1是标准输出,那么这条命令不就是相当于把标准错误重定向到标准输出么?是的。

为什么是&1而不是1,这里& 符号是什么?& 符号可以理解为引用(reference)。&1 就是对标准输出的引用。

command>a 2>a 与 command>a 2>&1的区别

通过上面的分析,对于command>a 2>&1这条命令,等价于command 1>a 2>&1。

可以理解为执行command产生的标准输入重定向到文件a中,标准错误也重定向到文件a中。

那么是否就说command 1>a 2>&1等价于command 1>a 2>a呢?

其实不是,command 1>a 2>&1与command 1>a 2>a 还是有区别的,区别就在于前者只打开一次文件a,后者会打开文件两次,并导致stdout被stderr覆盖。&1的含义就可以理解为用标准输出的引用,引用的就是重定向标准输出产生打开的a。从IO效率上来讲,command 1>a 2>&1比 command 1>a 2>a的效率更高。

演示一下效果

//test.sh shell 程序
#!/bin/sh
t
date

其中t指令并不存在,执行会报错,会输出到stderr。date能正常执行,执行会输出当前时间,会输出到stdout。

chmod +x test.sh为test.sh增加执行权限。

执行 ./test.sh > test.log,如下所示:

我们发现 stderr 并没有被重定向到 test.log 中,stderr 直接输出到屏幕上了。

执行 ./test.sh > test.log 2>&1,如下所示:

这次,我们发现stdout 和 stderr 都被重定向到了 test.log 中了。

Java_supermanNO1:专注于Java开发技术的研究与知识分享!

————END————

  • 点赞(编辑不易,感谢您的支持)

  • 转发(分享知识,传播快乐)

  • 关注(每天更新Java开发技术)

2019-03-31 20:38:00 weixin_30617797 阅读数 14
  • 马哥Linux教程-Linux操作系统基础由浅入深全面讲解1

    本课程为全新马哥Linux全套系列课程之一--Linux基础入门和架构了解,从Linux起源,Linux架构和Linux形成历史开始逐步讲解,让你彻彻底底了解Linux的诞生,之后介绍了Linux相关文化和核心组成结构,以及Linux常用命令和基本用法,课程由浅入深,讲授方法受到98%学员一致好评!

    19684 人正在学习 去看看 马永亮

先说结论,

2>&1 的意思是,把标准错误(stderr)重定向到标准输出(stdout)

如果想了解为什么,可以继续阅读:

1和2 是什么

shell中,有一些常用的文件描述符(file descriptor):

0: 标准输入(stdin)
1: 标准输出(stdout)
2: 标准错误(stderr)

所以 2>&1 中的2就是标准错误,1就是标准输出。

> 符号是什么

">" 是shell中的重定向符, 例如:echo "abc" > file1 就是把abc写到文件名交file1的文件中。
其中要注意的是,一般"1>" 可以简写成">",也就是默认重定向是重定向标准输出。标准输入重定向用"<",标准错误重定向用"2>",这样三个标准文件描述符都能正确的区分重定向了。

&是什么

&符号在shell中有几个意思,在2>&1中, &用做一个“转义符”,和1结合,"&1"一起表示标准输出。
那为什么需要&呢?1不是已经表示标准输出了吗?
那我们假设我们用这样shell script:

cat file1 > outfile 2>1

那这样,系统就会认为,把标准错误输出到文件名是1的文件中。为了消除歧义,&1在这个情景下,才表示标准输出,否则单独的1,就是文件名为1的文件。
如果你看到一个script是:

cat file1 > outfile 2>&1 &

第二个&(command 最后的&),表示command在后台运行,意义与&1中的&不同。

这条命令背后是什么

如果想深入了解一下,可以继续阅读:
这个命令其实是一个dup2()调用。dup2的作用是复制一个现存的文件描述符。

dup2可以用newfd参数指定新描述符的数值,如果newfd已经打开,则先将其关闭。如果newfd等于oldfd,则dup2返回newfd, 而不关闭它。dup2函数返回的新文件描述符同样与参数oldfd共享同一文件表项。

dup2等效于:

close(oldfd);fcntl(oldfd, F_DUPFD, newfd);

用strace可以看到, command > file 2>&1 这个命令中实现重定向的关键系统调用序列是:

open(file) == 3
dup2(3,1)
dup2(1,2) 

参考文献

linux之dup和dup2函数解析
linux shell 中"2>&1"含义
shell重定向输出(1>&2 2>&1 &>file >&file)

转载于:https://www.cnblogs.com/youyoubaishu/p/10633011.html

2018-10-26 21:52:16 hyb612 阅读数 1309
  • 马哥Linux教程-Linux操作系统基础由浅入深全面讲解1

    本课程为全新马哥Linux全套系列课程之一--Linux基础入门和架构了解,从Linux起源,Linux架构和Linux形成历史开始逐步讲解,让你彻彻底底了解Linux的诞生,之后介绍了Linux相关文化和核心组成结构,以及Linux常用命令和基本用法,课程由浅入深,讲授方法受到98%学员一致好评!

    19684 人正在学习 去看看 马永亮

前言

有时候我们常看到类似这样的脚本调用:

./test.sh  > log.txt 2>&1

这里的2>&1是什么意思?该如何理解?
先说结论:上面的调用表明将./test.sh的输出重定向到log.txt文件中,同时将标准错误也重定向到log.txt文件中。

有何妙用

(如果已经明白是什么作用,可跳过此小节)
上面到底是什么意思呢?我们来看下面的例子,假如有脚本test.sh:

#!/bin/bash
date         #打印当前时间
while true   #死循环
do
    #每隔2秒打印一次
    sleep 2
    whatthis    #不存在的命令
    echo -e "std output"
done

脚本中先打印当前日期,然后每隔2秒执行whatthis并打印一段字符。由于系统中不存在whatthis命令,因此执行会报错。
假如我们想保存该脚本的打印结果,只需将test.sh的结果重定向到log.txt中即可:

./test.sh > log.txt

执行结果如下:

ubuntu$ ./test.sh >log.txt
./test.sh: 行 7: whatthis: 未找到命令

我们明明将打印内容重定向到log.txt中了,但是这条错误信息却没有重定向到log.txt中。如果你是使用程序调用该脚本,当查看脚本日志的时候,将会完全看不到这条错误信息。而使用下面的方式则会将出错信息也重定向到log.txt中:

./test.sh  > log.txt 2>&1

以这样的方式调用脚本,可以很好的将错误信息保存,帮助我们定位问题

如何理解

每个程序在运行后,都会至少打开三个文件描述符,分别是0:标准输入;1:标准输出;2:标准错误。
例如,对于前面的test.sh脚本,我们通过下面的步骤看到它至少打开了三个文件描述符:

./test.sh    #运行脚本
ps -ef|grep test.sh  #重新打开命令串口,使用ps命令找到test.sh的pid
hyb       5270  4514  0 19:20 pts/7    00:00:00 /bin/bash ./test.sh
hyb       5315  5282  0 19:20 pts/11   00:00:00 grep --color=auto test.sh

可以看到test.sh的pid为5270,进入到相关fd目录:

cd /proc/5270/fd   #进程5270所有打开的文件描述符信息都在此
ls -l              #列出目录下的内容
 0 -> /dev/pts/7
 1 -> /dev/pts/7
 2 -> /dev/pts/7
 255 -> /home/hyb/workspaces/shell/test.sh

可以看到,test.sh打开了0,1,2三个文件描述符。同样的,如果有兴趣,也可以查看其他运行进程的文件描述符打开情况,除非关闭了否则都会有这三个文件描述符。

那么现在就容易理解前面的疑问了,2>&1表明将文件描述2(标准错误输出)的内容重定向到文件描述符1(标准输出),为什么1前面需要&?当没有&时,1会被认为是一个普通的文件,有&表示重定向的目标不是一个文件,而是一个文件描述符。在前面我们知道,test.sh >log.txt又将文件描述符1的内容重定向到了文件log.txt,那么最终标准错误也会重定向到log.txt。我们同样通过前面的方法,可以看到test.sh进程的文件描述符情况如下:

 0 -> /dev/pts/7
 1 -> /home/hyb/workspaces/shell/log.txt
 2 -> /home/hyb/workspaces/shell/log.txt
 255 -> /home/hyb/workspaces/shell/test.sh

我们可以很明显地看到,文件描述符1和2都指向了log.txt文件,也就得到了我们最终想要的效果:将标准错误输出重定向到文件中
它们还有两种等价写法:

./test.sh  >& log.txt
./test.sh  &> log.txt

总结

我们总结一下前面的内容:

  • 程序运行后会打开三个文件描述符,分别是标准输入,标准输出和标准错误输出。

  • 在调用脚本时,可使用2>&1来将标准错误输出重定向。

  • 只需要查看脚本的错误时,可将标准输出重定向到文件,而标准错误会打印在控制台,便于查看。

  • >>log.txt会将重定向内容追加到log.txt文件末尾。

  • 通过查看/proc/进程id/fd下的内容,可了解进程打开的文件描述符信息。

本文最新内容地址如何理解Linux Shell中的2>&1

思考

下面的调用会将标准错误输出重定向到文件中吗?为什么?

./test.sh 2>&1 >log.txt 


推荐阅读:

C语言入坑指南-数组之谜

Linux常用命令-解压缩篇

变长参数探究

 

关注公众号【编程珠玑】,第一时间获取更多原创技术文章

 

 

 

2019-01-03 16:50:00 weixin_30544657 阅读数 2
  • 马哥Linux教程-Linux操作系统基础由浅入深全面讲解1

    本课程为全新马哥Linux全套系列课程之一--Linux基础入门和架构了解,从Linux起源,Linux架构和Linux形成历史开始逐步讲解,让你彻彻底底了解Linux的诞生,之后介绍了Linux相关文化和核心组成结构,以及Linux常用命令和基本用法,课程由浅入深,讲授方法受到98%学员一致好评!

    19684 人正在学习 去看看 马永亮

我们在写启动脚本的时候,会用nohup &,这个大家都知道,但是经常会有 >/dev/null 2>&1。比如

nohup java -jar xxx.jar >/dev/null 2>&1 &

这个到底表示什么意思

几个基本符号及其含义

  • /dev/null 表示空设备文件
  • 0 表示stdin标准输入
  • 1 表示stdout标准输出
  • 2 表示stderr标准错误

对于& 1 更准确的说应该是文件描述符 1,而1标识标准输出,stdout。

对于2 ,表示标准错误,stderr。

2>&1 的意思就是将标准错误重定向到标准输出。这里标准输出已经重定向到了 /dev/null。那么标准错误也会输出到/dev/null

可以把/dev/null 可以看作"黑洞". 它等价于一个只写文件. 所有写入它的内容都会永远丢失. 而尝试从它那儿读取内容则什么也读不到.

再说2>&1?

在>左边的2,表示stderr标准错误。不需要加&

但是在>右边的1必须加&,才表示stdout标准输出

如果不加&,表示的是文件名

另外>左边如果不加,默认是1

测试

ls 2>1测试一下,不会报没有2文件的错误,但会输出一个空的文件1;

ls xxx 2>1测试,没有xxx这个文件的错误输出到了文件1中;

ls xxx 2>&1测试,不会生成1这个文件了,不过错误跑到标准输出了;

ls xxx >out.txt 2>&1, 实际上可换成 ls xxx 1>out.txt 2>&1;重定向符号>默认是1,错误和输出都传到out.txt了。

转载于:https://www.cnblogs.com/wangsongbai/p/10215155.html

没有更多推荐了,返回首页