以守护进程身份运行Bash脚本
1. 概述
在本教程中,我们将学习如何在后台将 bash 脚本作为守护进程运行。
2. 以普通用户身份守护脚本
我们可以利用 bash 进程在后台运行我们的脚本。我们使用*&*运算符启动后台任务或进程。
例如,让我们守护这个我们放置在*/home/blogdemo/script.sh*的简单脚本:
# Print a message every 60 seconds.
while :; do
sleep 60
echo "Slept for 60 seconds!"
done
使用nohup 命令运行脚本可确保在我们退出终端时它不会被杀死:
$ nohup ./script.sh &
nohup: appending output to nohup.out
nohup将脚本的任何输出记录到nohup.out文件中:
$ cat nohup.out
Slept for 60 seconds!
Slept for 60 seconds!
...
我们可以在启动脚本后关闭终端。
为了杀死进程,我们可以将启动进程的 PID 记录到一个文件中,并与kill 一起使用:
$ nohup ./script.sh &
nohup: appending output to nohup.out
$ echo $! > ./script.pid
$ cat script.pid
4946
*$!*变量存储新启动进程的PID。因此,我们可以直接杀死脚本:
$ kill $(cat ./script.pid)
虽然我们在这里看到的方法很简单,但它确实需要额外的用户干预来启动和关闭脚本。
3. 守护脚本系统范围
我们刚刚学习了如何以普通用户的身份在后台运行脚本。现在,我们将介绍更复杂的方法,这些方法允许我们通过系统的服务管理器控制脚本。
3.1. 使用systemd
**我们可以使用systemd 单元文件 在启动时启动我们的脚本。**单元文件描述了系统应该如何执行给定的程序。
让我们在*/etc/systemd/system/script_daemon.service*创建一个单元文件:
[Unit]
Description=Script Daemon
[Service]
Type=simple
User=blogdemo
ExecStart=/home/blogdemo/script.sh
Restart=on-failure
[Install]
WantedBy=default.target
我们使用*User=选项设置脚本将运行的用户,并使用ExecStart=*选项设置脚本的路径。systemd.exec 手册页中记录了各种选项。 现在,让我们启用该服务:
$ sudo systemctl daemon-reload
$ sudo systemctl enable script_daemon.service
Created symlink /etc/systemd/system/shutdown.target.wants/script_daemon.service → /etc/systemd/system/script_daemon.service
在这里,我们重新加载systemd配置并使用systemctl 工具启用我们的服务,该工具有助于管理systemd服务。
我们还可以将依赖项添加到各种其他服务。
例如,我们可能希望在启动脚本之前确保网络可用。我们使用*After=*选项执行此操作:
[Unit]
Description=Script Daemon
After=network.target
[Service]
...
我们可以使用sudo systemctl restart script_daemon.service 重启服务。它将在启动时自动启动。
3.2. 使用*/etc/rc.local*
/etc/rc.local文件包含我们要运行的命令。因此,我们可以将脚本的路径附加到这个文件中:
$ echo "/home/blogdemo/script.sh" >> /etc/rc.local
默认情况下,该脚本以root用户身份执行。为了删除权限,我们可以使用su 以不同的用户身份执行命令:
$ echo "su - blogdemo /home/blogdemo/script.sh" >> /etc/rc.local
我们应该注意,该命令应该是从/etc/rc.local*运行的最后一个命令,因为它会阻止执行。*
为了使它成为非阻塞的,我们可以使用nohup命令和我们之前了解的*&*运算符。
此外,如果systemd可用,我们应该避免使用/etc/rc.local*文件的这种方法,因为它是一个遗留文件。*