• linux下 > /dev/null 2 > &1 的意思和如何在后台启动进程


    一、几个基本符号及其含义 

    之前看到别人写的一个shell脚本,有一个命令是:rm -f ${src_tmp_file} > /dev/null 2>&1

    现在大概明白是什么意思了

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

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

    >/dev/null

    这条命令的作用是将标准输出1重定向到/dev/null中。 /dev/null代表linux的空设备文件,所有往这个文件里面写入的内容都会丢失,俗称“黑洞”。那么执行了>/dev/null之后,标准输出就会不再存在,没有任何地方能够找到输出的内容。

    &1

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

    2

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

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

    rm -f ${src_tmp_file} > /dev/null 2>&1 其实等于 rm -f ${src_tmp_file} 1 > /dev/null 2>&1

    rm -f ${src_tmp_file} 1 > /dev/null 2>&1,可以看成三部分:
    1.命令:rm -f ${src_tmp_file}
    2. 1 > /dev/null:把这条删除命令的标准输出重定向到/dev/null(即不会显示)
    3. 2>&1:把错误输出重定向到标准输出,而上面把标准输出重定向到/dev/null,即错误输出也重定向到/dev/null
    4. 因此这条命令无论正确执行还是错误,都不会有任何显示

    二、测试

    ls 2 > a.txt:不会报没有2文件的错误,但会输出一个空的文件a.txt;

    ls xxx 2 > a.txt:会报错,没有xxx这个文件,但是错误信息输出到了文件a.txt中,不会显示在终端;

    ls xxx 2 > &1:错误跑到标准输出了;

    ls xxx > out.txt 2 > &1:等于 ls xxx 1 > out.txt 2 > &1;正确或者错误的信息都写到out.txt,不会显示在终端。

    三、如何在后台启动进程

    1、进程的启动方式

    1.前台启动:用户输入命令,直接执行程序
    2.后台启动:在命令行尾加入"&"符号,例如后台启动weblogic服务:nohup ./startWeblogic.sh &

    2、后台不挂断运行进程

    要想在后台不挂断运行进程,即使把终端关闭了也能继续运行的进程,单单使用"&"是不行的,
    因为"&"只能让进程在后台启动,如果关闭终端,这个进程还是会结束的,因此需要配合"nohup"命令使用

    命令使用
    nohup command > /dev/null 2>&1 &


    # 解释
    nohup:
    no hangup,不挂断地运行命令。只用nohup命令,关闭终端,进程还存在。若在终端中直接使用Ctrl+c,则会关闭进程。
    若没有指定标准输出和标准错误,那么所有输出都被重定向到一个名为nohup.out的文件中(比如:nohup command & )

    在 Unix 的早期版本中,每个终端都会通过 modem 和系统通讯。当用户 logout 时,modem 就会挂断(hang up)电话。 同理,当 modem 断开连接时,就会给终端发送 hangup 信号来通知其关闭所有子进程。
    
    那么如果我们需要某个命令长时间运行,什么方法能最简便的保证它在后台稳定运行呢?
    我们知道,当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程。
    因此,我们的解决办法就有两种途径:要么让进程忽略 HUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。  
    
    1. nohup
    nohup 无疑是我们首先想到的办法。顾名思义,nohup 的用途就是让提交的命令忽略 hangup 信号。
    
    2.setsid
    nohup 无疑能通过忽略 HUP 信号来使我们的进程避免中途被中断,但如果我们换个角度思考,如果我们的进程不属于接受 HUP 信号的终端的子进程,那么自然也就不会受到 HUP 信号的影响了。
    
    在linux下,一个session是由一组进程组构成的,每个进程组又由多个进程构成。
    
    # session创建
    session可以在任何时候创建,调用setsid函数即可,session中的第一个进程即为这个session的leader,leader是不能变的。常见的创建session的场景是:
    用户登录后,启动bash进程时将会创建新的session,bash进程会作为session的leader,随后bash里面运行的进程(不特殊处理)都将属于这个session。
    
    # 特点
    session的主要特点是当session的leader退出后,session中的所有其它进程将会收到SIGHUP信号,其默认行为是终止进程,即session的leader退出后,session中的其它进程也会退出。
    如果session和tty关联的话,它们之间只能一一对应,一个tty只能属于一个session,一个session只能打开一个tty。当然session也可以不和任何tty关联。
    
    # 使用
    只需要在命令使用前加上setsid就可以了,该方法的作用是新建一个新的session,使用户进程和bash不在同一个session,并使自己成为leader。
    hangup名称的来由

    command:
    command是用户输入的命令,可自行设置。如“java -jar crm.jar”等。

    &:
    后台运行。当你只使用“&”时,关闭终端,进程会关闭。

    建议:
    所以当你要让程序在后台不挂断运行时,需要将nohup和&一起使用。

    例如:nohup ./startWeblogic.sh > /dev/null 2>&1 &

    3、tips

    jobs:
    使用"jobs"可查看当前有多少在后台运行的命令。

    fg:
    将后台中的命令调至前台继续运行。如果后台中有多个命令,可以用"fg %jobnumber"(是jobs编号,不是进程号)将选中的命令调出。

    bg:
    将一个在后台暂停的命令,变成在后台继续执行。如果后台中有多个命令,可以用"bg %jobnumber"将选中的命令调出。

    kill %jobnumber: 终止后台进程。

  • 相关阅读:
    Github创建远程库
    注册和登录Github
    Github简介
    一个成都程序猿写于离开北京一周年与26岁生日的这一天。
    【原创】面试时遇到『看门狗』脖子上挂着『时间轮』,我就问你怕不怕?
    【编程玄学】一个困扰我122天的技术问题,我好像知道答案了。
    【原创】(求锤得锤的故事)Redis锁从面试连环炮聊到神仙打架。
    【原创】面试官:你回去等通知吧!
    【原创】面试官问我G1回收器怎么知道你是什么时候的垃圾?
    【原创】面试官:你说你熟悉jvm?那你讲一下并发的可达性分析
  • 原文地址:https://www.cnblogs.com/Zzbj/p/11953686.html
Copyright © 2020-2023  润新知