在远程登录服务器时,执行耗时久的命令,比如压缩或下载文件,受到网络波动导致 ssh 退出,会直接停止执行.
又或者希望程序一直在后台运行,不受干扰.可以使用 nohup
screen
命令来解决这些问题.
原因
当断开 ssh 连接时,终端会收到 hangup 信号从而关闭其所有子进程。
所以,解决办法大概有两种途径:
- 让进程忽略 hangup 信号
- 让进程的父进程不是当前终端
nohup
nohup 会使进程忽略 hangup 信号
默认会输出一个名叫 nohup.out
的文件到当前目录下
如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中
使用
nohup ping baidu.com
输出
nohup: ignoring input and appending output to ‘nohup.out‘
但是这个时候,只是挂起,没有放在放在后台,必须在命令后面加上 & 才可以在后台运行
nohup ping baidu.com &
忽略标准错误和标准输出
nohup ping baidu.com >/dev/null 2>&1 &
screen
可以打开多个伪终端,在伪终端运行命令
新建终端
screen -S new
这个时候直接在新终端运行命令, 使用 pstree
,看出 ping 的父进程为 screen
systemd─┬─AliYunDun───23*[{AliYunDun}]
├─nginx───nginx
├─sshd─┬─sshd───sshd───bash───screen───screen───bash───ping
│ └─sshd───sshd───bash───pstree
setsid
把进程的父进程改为 systemd 进程(pid 为1的进程)
setsid ping baidu.com >/dev/null 2>&1
使用 pstree -sp 进程id
, 可以看出父进程为 systemd
systemd(1)───ping(670631)
()
使用 ()
包裹命令,命令会在新的shell执行, 父进程id会是1
[root@golang ~]# (ping baidu.com > /dev/null 2>&1 &)
[root@golang ~]# ps -aux | grep ping
root 8375 0.0 0.2 55396 4920 pts/1 S 14:09 0:00 ping baidu.com
root 8381 0.0 0.0 12320 1076 pts/1 R+ 14:09 0:00 grep --color=auto ping
[root@golang ~]# pstree -ps 8375
systemd(1)───ping(8375)
``