当我用服务器终端跑一段代码,尤其是训练周期很长时,生怕屏幕黑掉、断网、关闭终端、电脑关机,如何将它放在后台,一直跑呢?
在VSCode远程连接服务器的情况下,可以使用以下几种方法确保程序在后台持续运行,即使关闭终端或VSCode也不会影响程序执行:
使用nohup命令
(适用于简单的任务,无需交互式操作)
nohup python your_script.py > output.log 2>&1 &
- nohup(no hang up):忽略挂起信号(SIGHUP),终端关闭后进程仍然运行
- >:将标准输出重定向到output.log,防止因无终端导致错误
- 2>&1:将标准错误输出合并到output.log中
- &:将程序放到后台运行。如果一条指令单加上它,则你可以继续在当前终端输入其它命令,无需等它完成或新开终端,但若关闭终端,它就会收到SIGHUP信号而终止
查看进程:
ps aux | grep your_script.py
- ps(process status):用于显示系统的进程信息
- a(all):显示所有用户的进程,但仅限于有控制终端的前台进程
- u(user format):以用户友好的格式显示(USER,PID,%CPU,%MEM,VSZ,RSS,TTY,STAT,START,TIME,COMMAND)
- x (without a controlling terminal):显示当前用户的所有进程,包括有控制终端(TTY=pts/<系统动态分配的伪终端编号>)前台进程和无控制终端(TTY=?)的后台进程
- |(管道操作符):这个符号将ps aux(列出系统中的所有进程)的输出结果传递给grep your_script.py进行过滤
- grep是一个文本搜索工具,这里用于在所有进程列表中搜索包含your_script.py的行,这样就只有包含your_script.py的进程才会被显示
终止进程(-9选项,即SIGKILL信号是无法被进程捕获、忽略或处理的,一般对正常用户进程都有效):
kill -9 <PID>
nohup默认忽略标准输入(stdin),如果程序需要用户输入会怎么样?卡住(阻塞)或受到“stdin: is not a tty”错误。如果输入可以是静态的,还是可以提供文件,用重定向方式输入啦:
nohup my_script.sh < input.txt > output.log 2>&1 &
要交互式输入的话就换下面的方法吧。
使用screen
(适用于需交互的任务,如查看日志、调试等)
1. 启动一个screen会话:
screen -S my_session
2. 在screen会话中运行你的程序:
python your_script.py
3. 退出screen(不终止程序):按Ctrl+A,然后按D
4. 重新进入screen会话:
screen -r my_session
5. 终止screen会话:在screen内输入exit退出会话,或直接Ctrl+C终止程序
使用tmux
(与screen类似,但支持更丰富的窗口管理)
1. 创建新的tmux会话:
tmux new -s my_session
2. 运行你的程序:
python your_script.py
3. 分离会话(不终止进程): 按Ctrl+B,然后按D
4. 重新连接tmux会话:
tmux attach -t my_session
5. 终止tmux会话:在tmux内输入exit,或直接Ctrl+C终止程序
使用systemd
(适用于长期运行的服务)
1. 创建服务文件:
sudo nano /etc/systemd/system/my_service.service
以超级用户(root)权限使用nano文本编辑器打开或创建/etc/systemd/system/my_service.service文件,通常用于定义一个systemd服务。systemd是Linux现代的初始化系统(init system),用于管理系统服务,文件路径/etc/systemd/system表示用户定义的服务(系统级别),.service文件通常用于创建自定义的后台服务,例如自动运行Python脚本、Web服务器、日志收集器等。
2. 添加以下内容:(打不出INI格式的高亮)
.ini
[Unit]
Description=My Python Script ; 服务描述
After=network.target ; 确保网络启动后再启动该服务
[Service]
ExecStart=/usr/bin/python3 /path/to/your_script.py ; 运行 Python 脚本
WorkingDirectory=/path/to/ ; 设置工作目录
Restart=always ; 进程崩溃时自动重启
User=your_user ; 指定运行的用户
[Install]
WantedBy=multi-user.target ; 使服务在多用户模式下启动(即开机自启)
编辑完成后按以下快捷键:Ctrl+X退出编辑器,输入Y确认保存,按Enter保存文件,然后运行以下命令以使systemd识别新服务
3. 重新加载systemd配置:
sudo systemctl daemon-reload
4. 启动服务:
sudo systemctl start my_service
5. 设置/禁用开机自启
sudo systemctl enable/disable my_service
6. 查看服务状态
sudo systemctl status my_service
7. 停止服务
sudo systemctl stop my_service
写在最后,我目前只会用到nohup,screen和tmux这种能交互的我也用不上,都要交互了还放啥后台,systemd我没权限😀 先码住,后面实操要用了再改