程序后台执行
nohup 和 &
nohup(n ohang up)的意思是不挂起、永久执行。 nohup运行命令可以使运行的命令永久的执行下去,和用户终端没有关系,可以在你退出帐户/关闭终端之后继续运行相应的进程。例如我们断开SSH连接并不会影响他的运行(注意:nohup没有后台运行的意思,&才是后台运行)。
&是指在后台运行,当用户退出(挂起)、关闭终端的时候,后台运行的这条命令也会退出。
所以,想要后台运行,而且会话退出后程序也能正常运行,可以把 nohup 和 & 结合使用。
先看一下一条实际的命令:
nohup python server.py &
# 日志输出到log文件
nohup python server.py > python.log 2>&1 &
# 输出到 /dev/null,即忽略输出
nohup python3 script.py >/dev/null 2>&1 &
Linux系统预留可三个文件描述符:0、1和2,他们的意义如下所示:
0——标准输入(stdin)
1——标准输出(stdout)
2——标准错误(stderr)
/dev/null
是一个特殊的设备文件,这个文件接收到任何数据都会被丢弃。因此,null这个设备通常也被称为位桶(bit bucket)或黑洞。
在 nohup python3 script.py >/dev/null 2>&1 &
中:
- >/dev/null
相当于 1>/dev/null
表示标准输出重定向到null,就是不输出任何东西;
- 2>&1
2重定向到地址1,即标准错误输出重定向到标准输出,由于前面标准输出重定向到null,所以标准错误也不输出任何东西;
- &
最后的&表示后台执行这条命令。
总结, nohup python3 script.py >/dev/null 2>&1 &
意思是后台执行脚本,不会看到输出,并且挂起,当关闭终端/退出账户的时候,脚本也能继续执行。
systemd
systemd service,系统和服务管理器。
unit的文件位置一般主要有三个目录:
Table 1. Load path when running in system mode (--system).
┌────────────────────────┬─────────────────────────────┐
│Path │ Description │
├────────────────────────┼─────────────────────────────┤
│/etc/systemd/system │ Local configuration │
├────────────────────────┼─────────────────────────────┤
│/run/systemd/system │ Runtime units │
├────────────────────────┼─────────────────────────────┤
│/lib/systemd/system │ Units of installed packages │
└────────────────────────┴─────────────────────────────┘
这三个目录的配置文件优先级依次从高到低,如果同一选项三个地方都配置了,优先级高的会覆盖优先级低的。其中 /usr/lib/systemd/system
其实是的软链接.
systemd service 配置文件均以 .service 为后缀,服务配置文件统一放在 /lib/systemd/system
,同时暴露一个可供用户存放的服务配置文件的目录 /etc/systemd/system
,如果用户需要,新建的服务配置就放在这个目录下。
以下是一个 unit 例子:
[Unit]
Description=Python Server
After=network.target
[Service]
WorkingDirectory=/path
User=root
Type=idle
ExecStart=/usr/bin/python3 /path/server.py
Restart=always
[Install]
WantedBy=multi-user.target
# 添加或修改后须重新加载systemd
systemctl daemon-reload
# 启动服务
systemctl start {service-name}
# 服务状态
systemctl status {service-name}
# 停止服务
systemctl stop {service-name}
# 重启服务
systemctl restart {service-name}
# 设置开机启动
systemctl enable {service-name}
# 设置取消开机启动
systemctl disable {service-name}
# 查看服务日志。-u 指定unit,-f 跟随输出
journalctl -u {service-name} -f
参考: https://systemd-book.junmajinlong.com/service_1.html http://www.jinbuguo.com/systemd/systemd.service.html#%E9%80%89%E9%A1%B9 https://www.cnblogs.com/TonvyLeeBlogs/articles/13762400.html
tmux
terminal multiplexer(终端复用器),可以保持 tmux 的会话以达到后台运行的效果。
screen
screen是一款由GNU计划开发的用于命令行终端切换的自由软件。
先按 Ctrl-A 再按 Ctrl-D 暂时断开 (detach)会话。这也是判断是普通窗口和 screen 的一种方法,普通窗口会直接关闭。
如果在会话中直接按 Ctrl-D 或输入 exit 会直接删除会话,不可恢复。
总结: - 在Attached状态下,按Ctrl+D 或输入exit,都会直接删除创建的会话,不能在激活! - 在Attached状态下,直接叉掉终端,此时会话状态变成Detacted,表示挂起虚拟终端,如果此时有运行的程序也就变成在后端运行了,可以通过screen -r ID/session_name 重新打开会话! - 在Attached状态下,按Ctral+a,再按d,此时会退出并挂起虚拟终端(保存会话,后台运行该虚拟终端),此时会话状态变成Detacted - 在Attached状态下,按Ctral+a,再按k(kill),此时会关闭对话,等同输入:exit - 在Attached状态下,按Ctral+a,再按c(create):新建一个虚拟终端 - 在Attached状态下,按Ctral+a,再按?:显示所有绑定键盘
在进入会话时,按Ctrl+D 或 输入exit 回车就会退出,并删除会话,此时使用screen -ls就看不到该会话了!
supervisor
Supervisor 是使用python开发的一个进程管工具,一般
安装:
配置文件路径 /etc/supervisor/supervisord.conf
子进程配置文件 /etc/supervisor/conf.d/*.conf
写一个测试脚本 echo_time.sh,间隔两秒输出时间:
在/etc/supervisor/conf.d/
新增子进程配置文件 echo_time.conf
:
[program:echo_time]
command=sh /tmp/echo_time.sh
priority=999 ; the relative start priority (default 999)
autostart=true ; start at supervisord start (default: true)
autorestart=true ; retstart at unexpected quit (default: true)
startsecs=10 ; number of secs prog must stay running (def. 10)
startretries=3 ; max # of serial start failures (default 3)
exitcodes=0,2 ; 'expected' exit codes for process (default 0,2)
stopsignal=QUIT ; signal used to kill process (default TERM)
stopwaitsecs=10 ; max num secs to wait before SIGKILL (default 10)
user=root ; setuid to this UNIX account to run the program
log_stdout=true
log_stderr=true ; if true, log program stderr (def false)
logfile=/tmp/echo_time.log
logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
logfile_backups=10 ; # of logfile backups (default 10)
stdout_logfile_maxbytes=20MB ; stdout 日志文件大小,默认 50MB
stdout_logfile_backups=20 ; stdout 日志文件备份数
stdout_logfile=/tmp/echo_time.stdout.log
重新读取配置、更新子进程组,启动程序:
看下日志:
supervisorctl 查看子进程运行:
$ sudo supervisorctl
supervisor> help
default commands (type help <topic>):
=====================================
add exit open reload restart start tail
avail fg pid remove shutdown status update
clear maintail quit reread signal stop version
supervisor> status
echo_time RUNNING pid 254384, uptime 0:00:42
supervisor>stop all
echo_time: stopped
supervisor> status
echo_time STOPPED May 14 11:43 PM
supervisor> start echo_time
echo_time: started
supervisor> tail -f echo_time
==> Press Ctrl-C to exit <==
2023-05-14,23:42:46
2023-05-14,23:42:48
2023-05-14,23:42:50
pstree
可以看到 supervisord 是 systemd 的子进程,同时后面的 sh sleep 是 supervisord 子进程 echo_time
systemd─┬─ModemManager───2*[{ModemManager}]
├─NetworkManager───2*[{NetworkManager}]
├─supervisord───sh───sleep
参考 https://juejin.cn/post/6844903745587773448