栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

标准输入、标准输出、标准错误(以及前后台启动程序)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

标准输入、标准输出、标准错误(以及前后台启动程序)

之前一直想写一篇文章总结下,标准输入、标准输出、标准错误,以及我们在前台启动一个程序,以及后台启动一个程序,和这三个之间的关系

1.标准输入、标准输出、标准错误

首先这三个对应的是三个文件描述符,这三个对应的文件描述符数值是 0,1,2,而这三个文件描述符是共享的,也就是每一个打开的终端都共享这三个文件描述符,看下下面的表格:

当执行shell命令时,会默认打开3个文件,每个文件有对应的文件描述符来方便我们使用:

类型文件描述符默认情况对应文件句柄位置
标准输入(standard input)0从键盘获得输入/proc/self/fd/0
标准输出(standard output)1输出到屏幕(即控制台)/proc/self/fd/1
错误输出(error output)2输出到屏幕(即控制台)/proc/self/fd/2

所以我们平时在执行shell命令中,都默认是从键盘获得输入,并且将结果输出到控制台上。但是我们可以通过更改文件描述符默认的指向,从而实现输入输出的重定向。比如我们将1指向文件,那么标准的输出就会输出到文件中。

比如现有文件a.log
文本内容为:this is a.log
当我们执行命令cat a.log时,系统默认将其输出到标准输出也就是屏幕,通过符号>我们可以将其输出重定向到另一个文本里:
cat a.log > copya.log
此时我们可以看到copya.log里的文本内容为:this is a.log
事实上,上述命令实际是 cat a.log 1> copya.log的缩写,表示把命令cat a.log的标志输出重定向到copya.log
注意1>是紧挨着的 不能分开写

也就是我们平时的 > 重定向符号 相当于  1>

同样,如果想把标准错误重定向到另一个文件里可以如下操作:

cat notexist.log 2> err.log
因为notexist.log不存在,直接执行cat notexist.log报错如下:
cat: notexist.log: No such file or directory
我们打开err.log会发现内容和上面一样,表示把命令的cat: notexist.log的标志错误输入到err.log里面了

一些特殊符号的含义:

> 等价于 1>也就是代表命令的标准输出
/dev/null 可以看作黑洞,等价于一个只写文件。所有写入它的内容都会永远丢失,尝试从它那儿读取内容则什么也读不到。
2表示stderr标准错误
&表示等同于的意思,2>&1,表示2的输出重定向等同于1

2.前后台启动程序和标准输出,标准错误的对应关系

前台启动,我们可以看到直接在终端上就是打开一个目录,执行相应的可执行文件就可以了,

然后默认对应的标准输出,和错误输出都是对应这个终端控制台。

具体我参考了一篇知乎上的文章:

详解Linux中nohup和&的用法和区别 - 知乎 示例

我们用c代码main.c 做示例,代码的作用是循环输出10000次的hello world!,每次输出后sleep 1秒:具体代码如下:

1 #include 
  2 #include 
  3 int main(void){
  4 for(int i=0;i<10000;i++){
  5 sleep(1);
  6 printf("hello worldn");
  7 }
  8 }

gcc main.c -o zzz

生成可执行文件 zzz,如下图,开始执行,每隔1s输出一个helloworld,然后当我按下ctrl+c 以后,程序收到信号SIGINT,自然终止:

hczhang@hczhang-OptiPlex-3050:~/testcommono/testnohup$ ./zzz
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
^C
hczhang@hczhang-OptiPlex-3050:~/testcommono/testnohup$
&

使用 ./zzz  &,效果如下所示:

[1] 21341
hczhang@hczhang-OptiPlex-3050:~/testcommono/testnohup$ hello world
hello world
hello world
hello world
^C
hczhang@hczhang-OptiPlex-3050:~/testcommono/testnohup$ hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world

看到我中间有一次使用了,ctrl+c  发出中断信号,但是退不出来,还是会继续执行,输出hello world,总结如下

首先会在终端显示进程号是21341键入Ctrl + C,发出SIGINT信号,程序会继续运行关掉session,程序会收到一个SIGHUP信号,通过ps aux | grep zzz 可以看到,进程21341也关闭了 nohup

1、使用nohup ./zzz ,效果如下:

hczhang@hczhang-OptiPlex-3050:~/testcommono/testnohup$ nohup ./zzz
nohup: ignoring input and appending output to 'nohup.out'



1)前台没有出现进程号

2)有一个“忽略输入并把输出追加到"nohup.out"”的提示

3)hello world 的输出也没有出现在前台

2、如果关掉session,程序会不会关闭呢?

1)使用ps aux | grep zzz 查看进程号

2)关掉session,程序会收到一个SIGHUP信号

3)再次使用ps aux | grep zzz,发现进程仍然存在

4)kill掉进程

3、测试一下Ctrl +C

使用nohup启动zzz,如果键入Ctrl+C ,程序收到SIGINT信号后,直接关闭了

&和nohup同时使用

nohup (no hangup 不挂起)放在命令的前面; 标准输出和标准错误缺省会被重定向到nohup.out 文件中。

1、使用nohup ./zzz  &运行程序,效果如下:

hczhang@hczhang-OptiPlex-3050:~/testcommono/testnohup$ nohup ./zzz &
[1] 26514
hczhang@hczhang-OptiPlex-3050:~/testcommono/testnohup$ nohup: ignoring input and appending output to 'nohup.out'

2、键入Ctrl + C,发送SIGINT信号 使用ps aux查看,进程仍然存在

3、关闭session,发送SIGHUP信号 使用ps aux查看,进程依然存在

4、如果想要终止进程的话,只能使用kill了

总结

1、使用&后台运行程序:

1)结果会输出到终端

2)使用Ctrl + C发送SIGINT信号,程序免疫

3)关闭session发送SIGHUP信号,程序关闭

2、使用nohup运行程序:

1)结果默认会输出到nohup.out

2)使用Ctrl + C发送SIGINT信号,程序关闭

3)关闭session发送SIGHUP信号,程序免疫

3、平日线上经常使用nohup和&配合来启动程序:

同时免疫SIGINT和SIGHUP信号,同时把标准错误和标准输出都重定位到黑洞文件里!

nohup ./zzz > /dev/null 2>&1 &

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/746771.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号