浅析 在Linux下【&命令】和【Nohup命令】的运用

浅析很详细。因此文章较长,阅读时间10~20分钟。自行考虑。


因为,最近一直在用【&】和【nohup】命令。就想查阅一下资料,来个详细了解 顺便整理出来。

首先要了解 一个知识点:

 & 和 nohup 的区别:
  【& : 指在后台运行】    

  nohup:不挂断的运行,全称:( no hang up) ,不挂起的意思 。就是指,用 nohup 命令 运行启动进程,可以使 启动的进程 永久的执行下去,和用户终端没有关系。

  例如,我们断开SSH连接都不会影响他的运行,但是 nohup 并没有后台运行的功能。

  &:是指 让程序 脱离了终端,放置到系统后台运行。这样不会占据终端,我们可以用终端做别的事情。


实例测试 【&】命令开始:

  测试启动,Linux ----> gs4文件夹下的 rungs 。     (rungs 进程启动文件,gs4 进程名称)

          

   前台启动:(能看到滚动很多 任务输出信息,当看到有 报错信息时,可以直接 Ctrl+C 终止进程)

 1 [root@ecs-linux-byx gs4]# ./rungs
 2 PDB is initialized by vmmemlib.
 3 Connect to DAS for authenticating...
 4 OK
 5 Done of init_startup_module.
 6 Not exists online_update file.
 7 Done of init_compile_module.
 8 Done of init_sql_module.
 9 Create ID pool, from 10000, total 400000.
10 Done of init_id_module.
11 Done of init_iid_module.
12 ...
13 ^C
14 [root@ecs-linux-byx gs4]# ^C
15 [root@ecs-linux-byx gs4]# ^C
16 [root@ecs-linux-byx gs4]# ^C

  Ctrl+C 终止进程后,查询进程列表,发现并没有gs4进程:(看来前台启动可以随时停止)

1 [root@ecs-linux-byx gs4]# ps -ef|grep gs4
2 [root@ecs-linux-byx gs4]# 

  & 后台启动:(在命令的末尾加上一个 & 号,将这个任务放到后台去执行)

 1 [root@ecs-linux-byx gs4]# ./rungs &
 2 PDB is initialized by vmmemlib.
 3 Connect to DAS for authenticating...
 4 OK
 5 Load: /gs/daemons/tasks/xianmolu/script_chuzhi-zhenqing.c... OK
 6 Load: /gs/daemons/tasks/xianmolu/script_dahuo-dexiao.c... OK
 7 Load: /gs/daemons/tasks/xianmolu/script_miju-nanjie.c... OK
 8 Load: /gs/daemons/tasks/xianmolu/script_hunji-mojun.c... OK
 9 ....
10 ^C
11 [root@ecs-linux-byx gs4]# ^C
12 [root@ecs-linux-byx gs4]# ^C
13 Load: /gs/daemons/tasks/party/sub_tasks/script_party_tunjiwuzi.c... OK
14 Load: /gs/daemons/tasks/party/sub_tasks/script_party_chushemieshu.c... OK
15 Load: /gs/daemons/tasks/party/sub_tasks/script_party_songyao.c... OK
16 Load: /gs/daemons/tasks/party/sub_tasks/script_party_zhilishuihuan.c... OK
17 
18 Start service on port: 8163
19 Done of init_service_module.
20 No online update.
21 Recovering for backup data of special modules not finished.
22 Please do check and restart if server has been reduced.
23 Game server allows user to login now.
24 *** Bad command (3A01) from client 50004 ***

  看着别晕,我是懒,直接复制了很多进程内容,但是关键操作,我都是标 黄了。看关键操作就可以了。

  后台启动。启动程序加了 & ,就变成了 将这个任务 放到后台去执行。任务被放到 后台执行之后,就可以立即继续在同一个终端上工作了,甚至关闭终端也不影响这个任务的正常执行

  测试结果一:

  这个进程,即使发现加上了 & ,前台还是会滚动很多 进程输出内容,直至程序启动完毕。即便,我途中按了很多次Ctrl + C ,也是徒劳无用。(见上图~)  

  因此也是有个新的知识点需要注意:如果这个进程任务 要求 输出内容  到 标准输出 中(例如 echo 或 ls),即使使用了 &,也会等待这些输出任务在前台运行完毕。

  测试结果二:

  这个进程启动需要1分钟,滚动输出内容也很多,看着很乱,进程加上& ,就直接关闭会话窗口。

  过几分钟后,查询进程列表,发现已经启动完毕。看来关闭终端确实不会影响 后台任务的正常执行。(如下图:)

1 [root@ecs-t6-large-2-linux-20191006000012 gs4]# ps -ef|grep gs4|grep -v grep
2 root     15160 15159  2 11:01 pts/1    00:00:46 ./gs4 /r ./ /e /gs/pack_data/lib_gs32.pak/gs/start_gs.o L --enable-socket-daemon 0 --stack-size 1024

  【&】命令的总结:

  1. 当使用 & 将一个进程放置到后台运行的时候,你并不能用Ctrl + C 来结束进程。但是Bash 会显示这个进程的进程 ID。在 Linux 系统中运行的每一个进程都有一个唯一的进程 ID,你可以使用进程 ID 来暂停、恢复或者终止对应的进程,因此进程 ID 是非常重要的。
  2. 在命令的末尾加上 & 可以让我们理解 前台进程 和 后台进程 的概念,让我们更好的管理这些进程。
  3. 在 UNIX/Linux 术语中,在后台运行的进程被称为 守护进程。如果你曾经听说过这个词,那你现在应该知道它的意义了。
  4. 和其它符号一样,& 在命令行中还有很多别的用法。例如:大文件的复制和移动,太费时间,突然断网怎么办?突然断电怎么办?不如在 操作后面 加个 & 试试?

实例测试 【nohup】命令开始:

命令一: nohup ./rungs 

    将 rungs 任务放到后台,关闭 标准输入,终端不再能够接收任何输入(标准输入)。

  【标注】:可能有的人看不懂 上面标记的话,简单理解就是,你用了这个指令之后,当前的shell 输入框就已经不能用了。需要打开新的指令框。

       如下图:即便我按了几次回车,或按任何键都已经不给 shell 命令输入框了。

  重定向 标准输出标准错误  到 当前目录下 的 nohup.out 文件,即使关闭远程工具(xshell,FinalShell等) 退出当前 session 依然继续运行。

1 [root@ecs--linux-byx gs4]# nohup ./rungs
2 nohup: 忽略输入并把输出追加到"nohup.out"
3. 
4.
5.

  用了  nohup 指令,当前目录下 会生成一个nohup.out 文件,记录了 标准输出标准错误

           

命令二:nohup ./rungs &

  nohup 和 & 组合。在要运行后台中的 nohup 命令,添加 & ( 表示“and”的符号)到命令的尾部。

   rungs 任务放到后台,但是 依然可以使用标准输入,终端能够接收任何输入。

  重定向 标准输出标准错误 到当前目录下的 nohup.out 文件,即使关闭xshell退出当前session依然继续运行。

[root@ecs--linux-byx gs4]# nohup ./rungs &
nohup: 忽略输入并把输出追加到"nohup.out"

           

 命令三:nohup ./rungs >/dev/null &

  经过上面两种方法,最后的截图文件。可以看出:

  每次用 nohup命令 重启一次进程任务后,本目录下的 nohup.out 文件 就会变大一次。日志不断积累增大 到特别大的时候,可能就会影响系统无法使用。

  这是因为,使用 nohup命令 提交作业,在缺省情况下 该作业的所有输出都被重定向到一个名为 nohup.out 文件 中。

       因此在这里,就可以说一下  /dev/null 文件的作用,可以看作"黑洞",它等价于一个只写文件。

  【所有写入它的内容都会永远丢失。而尝试从它那儿读取内容则什么也读不到。因此这也是一个无底洞,任何东西都可以定向到这里,但是却无法打开。 】

  所以一般很大的 标准输出 stdou标准错误stderr ,或是你不关心的 标准输出 stdou 标准错误stderr 。都可以定向到这里 >/dev/null

  当然你还可以改重定向文件。这里可以看 命令四。

1 [root@ecs-linux-byx gs4]# nohup ./rungs >/dev/null &
2 [1] 15321
3 [root@ecs-linux-byx gs4]# nohup: 忽略输入重定向错误到标准输出端

命令四:nohup ./rungs > mylog 2>&1 &

  这个命令 应该是 日常运维中 用的比较多 。

  意思是,将 rungs程序中 所有的 标准输出  错误输出  都将被重定向到一个叫做 mylog 的文件中。即输出内容不打印到屏幕上,而是输出到 mylog文件中。

  避免了多个进程都 默认定向到 nohup.out 文件中比较乱。运维起来不方便。

  

  下来就是 2>&1 解析说明。看不懂,那就知道这么写就可以了。

  首先我们要了解 ,操作系统中有三个常用的流:
  • 0:标准输入流 stdin
  • 1:标准输出流 stdout
  • 2:标准错误流 stderr
  例如,当我们用 > mylog.txt,实际是 1>mylog.txt 的省略用法;< mylog.txt ,实际是 0 < mylog.txt 的省略用法。
 
  这样 我们 就大概 知道了 命令四 中的   2>&1的意思:
  这个意思是把  [标准错误(2)]  重定向到 [标准输出中(1)],而 标准输出 又导入文件mylog 里面,所以结果是 [标准错误] [标准输出] 都导入文件 mylog 里面了。
    
  其中,至于为什么需要将 标准错误 重定向到 标准输出 的原因,那就归结为 标准错误stderr 没有缓冲区,而 标注输出stdout 有。
  这就会导致当写成: >mylog 2>mylog ,文件 mylog被两次打开,而 标准错误stderr  标注输出stdout 将会竞争覆盖,这肯定不是我门想要的。
  也就是为什么有人会写成: nohup ./rungs >mylog 2>mylog 出错的原因了。
 
   接着说一下 &1?
  我们知道了 2>1代表什么,2 与 > 结合代表 标准错误stderr 重定向,不需要加& 。而1则代表 错误重定向到一个文件1,但不代表标准输出
  换成2>&1,&与1结合就代表
  1 表示 标准输出,stdout。如果不加&,表示的是文件名。而对于 &1 更准确的说应该是文件描述符
   最后一个&, 是让该命令在后台执行。
 
 
 
最后再说一个命令,和小细节。运维中肯定能用的到。

  命令清空日志:前面的命令有时会造成日志不断积累增大,无法使用,因此我们定期清理一下日志文件。

1 [root@ecs-linux-byx gs4]# cat /dev/null>mylog
 

  小细节:大多数人在使用了 nohup 命令之后就认为大功告成。然后当前账号非正常退出,或直接关闭了终端。结果有时候就会导致,命令自己异常结束了。

  所以在使用 nohup命令后,需要按终端上键盘 任意键 退回到shell输入命令窗口,同时尽量使用 exit 正常退出终端,万无一失保证命令一直在后台运行。

  避免了因直接点关闭程序按钮关闭终端,从而断掉该命令所对应的session,导致nohup对应的进程被通知需要一起 shutdown 的尴尬。

 希望可帮到你。

by不言谢。

猜你喜欢

转载自www.cnblogs.com/byx1024/p/12221167.html