欢迎光临
我们一直在努力

AutoDL关闭终端或网络中断不影响程序运行的方法

为什么需要 nohup 和 &?

我们先回顾一下您遇到的问题:

  • 直接运行 python train.py:进程在前台运行,完全依赖于当前的终端连接。一旦连接断开(断网、关机、关闭窗口),进程就会被系统“挂断”(Hang Up),从而被终止。

nohup 和 & 就是为了解决这个问题而生的。


“黄金命令”的详细分解

这是一个最常用、最规范的格式:

nohup python -u train.py > train.log 2>&1 &

让我们像剥洋葱一样,一层一层地看懂它:

1. python train.py
  • 这是核心:您真正想要执行的命令。它可以是 python your_script.py –args, sh run.sh, 或任何其他需要在后台长时间运行的程序。
2. & (Ampersand / 和号)
  • 作用:将命令放入后台 (Background) 运行。
  • 效果:当您输入 command & 并回车后,终端不会等待命令执行完毕,而是会立即返回一个进程ID(PID),然后您马上就可以输入新的命令了。它“解放”了您的终端。
  • 不足:单独使用 & 时,如果终端关闭,它还是有可能会被系统终止。所以它需要和 nohup 配合。
3. nohup (No Hang Up)
  • 作用:让进程忽略“挂断”信号 (SIGHUP)。
  • 效果:这是最关键的一步。当您关闭终端或连接断开时,系统会向所有子进程发送“挂断”信号。nohup 命令告诉您的 python train.py 进程:“请忽略这个信号,继续活下去!”
  • 结合 &:nohup command & 组合起来就是:在后台运行一个命令,并且让它在终端关闭后也继续运行。
4. > 和 train.log
  • 作用:重定向标准输出 (stdout)。
  • >:是重定向符号,意思是“把左边命令的输出,写入到右边的文件里”。如果文件已存在,会覆盖原有内容。
  • train.log:您指定的日志文件名。所有原本应该打印在屏幕上的信息(比如 print() 语句、模型的训练进度条等)现在都不会显示在屏幕上,而是会全部被写入到 train.log 这个文件中。这对于记录和排查问题至关重要。
5. 2>&1
  • 作用:重定向标准错误 (stderr) 到标准输出 (stdout)。
  • 分解:
    • 在Linux中,0 代表标准输入,1 代表标准输出 (stdout),2 代表标准错误 (stderr)。
    • 2> 的意思是“重定向标准错误”。
    • &1 的意思是“到标准输出当前所在的位置”。
  • 整体理解:因为前面 > 已经把标准输出 (1) 重定向到了 train.log,所以 2>&1 的意思就是“把标准错误也重定向到 train.log 文件中”。
  • 为什么这很重要:这样一来,无论是正常的打印信息,还是程序出错时的报错信息(比如Python的Traceback),都会按照时间顺序一起保存在 train.log 这同一个文件里,极大地利于您诊断问题。
6. -u

为了提高效率,当一个程序(比如您的Python脚本)的输出被重定向到一个文件时,系统不会每产生一点点输出(比如一个 print 语句)就立刻去写一次硬盘文件(因为频繁写硬盘很慢)。

相反,它会像这样工作:

  • 攒着输出:程序会先把输出内容(比如你的训练日志)暂存在一块内存区域里,这块区域就叫缓冲区 (Buffer)。
  • 凑够了再写:它会等到缓冲区被装满了(比如凑够了4KB或8KB的数据),或者等到程序执行结束时,才把缓冲区里的所有内容一次性写入到硬盘上的 train.log 文件里。
  • 这就导致了一个问题: 当您在后台运行训练任务,并使用 tail -f train.log 想要实时监控进度时,您会发现终端里长时间没有任何动静。然后,过了好几分钟,日志文件里会突然“喷出”一大段积攒已久的日志。如果程序在这期间崩溃了,那些还暂存在缓冲区里没来得及写入文件的日志就永远丢失了。

    -u 的作用:实时写入,当您使用了 python -u train.py 时,您等于在告诉Python解释器: “请不要使用输出缓冲!任何 print 语句或错误信息,都请立刻、马上、直接写入到它该去的地方(在您的例子里就是 train.log 文件)。”


    实战演练:如何使用和管理

    步骤1:启动任务
  • 通过 SSH 或 JupyterLab Terminal 连接到您的 AutoDL 服务器。
  • cd到您的项目代码所在的目录。
  • 执行您的“黄金命令”:

    nohup python train.py –epoch 100 –batch_size 32 > my_training.log 2>&1 &

  • 按下回车后,您会看到类似下面的输出,然后光标会回到命令行,等待您输入新命令。

    [1] 12345

    这里的 12345 就是您的训练任务的进程ID (PID),可以先记下来。

  • 步骤2:监控任务进度

    您不能直接看到输出了,但可以通过查看日志文件来监控。

    # 实时滚动查看日志文件的最新内容 (按 Ctrl+C 退出)
    tail -f my_training.log

    # 查看日志文件的最后200行
    tail -n 200 my_training.log

    # 查看整个日志文件 (按 q 退出)
    less my_training.log

    步骤3:确认任务是否仍在运行

    如果您过了一段时间想确认任务是否还在,可以用以下命令:

    # 查找包含 "python train.py" 的进程
    ps aux | grep 'python train.py'

    如果您看到除了 grep 命令本身之外,还有您的 python train.py 进程,那就说明它还在正常运行。

    或者,简单粗暴地:

    nvidia-smi

    看看GPU是否还在被 python 进程占用。

    步骤4:手动停止任务(如果需要)

    如果发现训练出错了,或者您想提前终止它,您需要手动“杀死”那个进程。

  • 先用 ps aux | grep 'python train.py' 找到它的 PID (比如是 12345)。
  • 执行 kill 命令: 

    # 优雅地终止进程 (推荐首选)
    kill 12345

    # 如果上面的命令杀不死,再用这个强制手段
    kill -9 12345


  • 总结与简化

    • 最完整的黄金命令 (推荐): nohup [你的命令] > [日志文件名] 2>&1 &
    • 懒人版 (也能用): nohup [你的命令] & 这种情况下,所有的输出会自动保存到一个名为 nohup.out 的文件里。
    赞(0)
    未经允许不得转载:171主机测评 » AutoDL关闭终端或网络中断不影响程序运行的方法
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址