写在前面
室友最近经常通过外部服务器运行深度学习训练程序, 服务器主机当然是基于命令行的Ubuntu, (或者red hat), 但是直接通过xterm运行总会出现重连之后程序运行中止
的问题, 因为我之前接触过一些简单的Linux shell运维, 在这里通过一个简单的命令搞定了这个问题.
下面主要在我的Mac上进行测试, 对于Linux可能在命令参数上略有不同, 这个稍后有提及.
Mac测试后台运行与实时输出
测试程序(tail_test.py
)如下, 一秒打印一个数字:
#!/usr/local/bin/python3
from time import sleep
for i in range(10000):
print(i)
sleep(1)
脚本文件(test.sh
, 这个名字在 kill
进程时候还会用到)设置为:
#!/bin/bash
/usr/local/bin/python3 -u tail_test.py
这时候需要先给脚本添加权限:
chmod 755 test.sh
使用的后台运行命令:
nohup ./test.sh > ret.txt 2>&1 &
这时候会给出进程号:
❯ nohup ./test.sh > ret.txt 2>&1 &
[1] 12889
完全退出终端, 再次进入, 通过下面的命令可以看出执行结果最新的几行.
❯ tail -f ret.txt
61
62
63
64
65
66
67
68
69
退出程序的话可以通过:
❯ ps aux|grep test
xxx 15454 0.0 0.0 408628368 1616 s000 S+ 9:36上午 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox test
xxx 12890 0.0 0.1 408865488 7984 ?? SN 9:33上午 0:00.06 /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/Resources/Python.app/Contents/MacOS/Python -u tail_test.py
xxx 12889 0.0 0.0 408628896 2000 ?? SN 9:33上午 0:00.00 /bin/bash ./test.sh
❯ kill -9 12889
❯ kill -9 12890
这时候看后台, test.sh
已经终止了.
关于命令的几点解释
这里面主要采用了Python
的命令行执行参数1, -u
, 细心的话在PyCharm运行Python文件时候应该可以发现这个参数, 就是动态刷新输出(不使用缓存)并显示.
然后是nohup
命令2, 不挂起运行命令. 可以在后台运行,
### 语法格式
nohup Command [ Arg … ] [ & ]
### 参数说明:
Command:要执行的命令。
Arg:一些参数,可以指定输出文件。
&:让命令在后台执行,终端退出后命令仍旧执行。
最后就是2>&1
了,将标准错误重定向到标准输出.
2022.4.6更新(使用tmux终端复用神器)
上面提到的使用nohup
命令的方法有一些弊端:
- 命令繁杂, 对初学者不太友好, 需要记住很多文件的位置(bash脚本, 以及Python执行文件), 当然 直接写在一行上不需要shell脚本也可以, 但是并不方便之后的维护.
- 输出的内容可能非常多, 这就导致最后的结果文档可能会非常大. 一个例子就是深度学习模型训练过程中, 因为epoch的增加导致的冗杂输出结果的增加, 打开最终的一个结果文档可能要花很长时间(这还是在确定电脑ram足够大的前提下).
- 后台管理比较麻烦. 如果需要中断程序的运行, 需要查询进程号并且杀死进程, 操作起来比较麻烦, 而且通过bash脚本运行Python文件的话,系统会同时开启两个人进程,
Python
和sh
, 这两个进程号连续的进程需要都被杀死才能终止正在运行的程序.
由于上面几点, 有位同学找到了更好的解决方案, 那就是终端复用器tmux
, 这个东西可以在后台执行终端, 相当于开启了一个新的会话, 这样的话就算关闭了ssh连接, 也能通过简单的命令找回之前的会话, 简单的两行命令就可以解决3.
# 新建会话, 在这里面输入要运行的命令, 默认的会话窗口标记为0
tmux
# 找回名称为0的会话
tmux attach -t 0
参考
-
[Linux nohup 命令 菜鸟教程 (runoob.com)](https://www.runoob.com/linux/linux-comm-nohup.html);