如何在云服务器上高效运行Python程序并实时监控

最近在服务器上跑一个任务,需要让程序在后台持续运行,即使我断开SSH连接也能正常工作。

1. 问题:如何查看正在后台运行的程序?

我一开始用的是最基础的 ps aux 命令。它能列出所有正在运行的进程,然后我通过 grep 过滤出我需要的Python程序。

ps aux | grep "python /data/Avatar/Wan2.2/generate.py"

但发现一个问题:当我尝试这么做时,终端返回的只有 grep 命令本身,这说明我的程序根本没有在运行。

详细解释一下 ps auxgrep 这两个命令的英文含义和具体作用。这部分内容通常是Linux系统管理员和开发者必备的知识。

ps aux

psProcess Status 的缩写,意思是“进程状态”。它的主要作用是显示当前系统中的进程信息。

aux 是三个不同的选项(option),它们通常组合在一起使用,但每个都有特定的含义:

  • a:代表 all,意思是“所有”。这个选项会显示所有终端上的进程,而不仅仅是当前终端的进程。
  • u:代表 user-oriented format,意思是“用户导向格式”。它会以更友好的方式展示进程信息,比如显示进程的CPU和内存使用率、启动该进程的用户名等。
  • x:代表 no-controlling-tty,意思是“没有控制终端”。这个选项会显示没有关联终端的进程,这些进程通常是系统在后台运行的服务或守护进程(daemon)。

所以,ps aux 的整体意思就是:以用户友好的格式,列出系统上所有进程(包括有终端的和没有终端的)的详细状态。

x 代表 no-controlling-tty 的设计,源于 Unix 系统中进程与终端之间的关系。


x 选项的由来

在 Unix/Linux 系统中,一个进程通常会与一个**控制终端(controlling terminal)**关联。这个终端是进程的输入来源和输出目的地。

  • 前台进程:当你直接在终端中运行一个程序(比如 ls),这个程序就是前台进程,它会和你的终端紧密相连。
  • 后台进程:而有些进程,比如系统服务(例如网站服务器、数据库),它们是在系统启动时自动运行的,没有直接与任何终端相连。这类进程被称为守护进程(daemon),它们在后台默默运行,不依赖用户的终端。

ps 命令的早期版本,默认只显示那些与当前终端关联的进程。这意味着,如果你想查看那些在后台独立运行的系统服务,常规的 ps 命令是看不到的。

为了解决这个问题,开发者添加了 x 选项。

  • x 选项让 ps 命令的行为发生了变化,它会“忽略”进程是否有控制终端(no-controlling-tty)这个条件。
  • 有了 x 选项,ps 就能显示所有进程,包括那些没有终端的守护进程。

因此,当你使用 ps aux 时,你看到的不只是你当前终端里运行的程序,还有系统里所有正在后台默默工作的进程。这个选项的设计正是为了让你能全面地掌握系统的运行状态。

ttyteletypewriter(电传打字机)的缩写。在现代的 Linux/Unix 系统中,它通常指的是终端(terminal)

这个词的起源非常有意思,它直接反映了计算机发展的历史。

tty 的词源

在计算机早期,人们使用一种叫做电传打字机的设备与计算机进行交互。这种设备类似于一台带键盘和打印机的打字机,用户在键盘上输入命令,电传打字机将这些命令转换成电信号发送给计算机,然后计算机将结果转换成电信号发回,通过打印机把结果打印在纸上。

所以,“tty” 这个词最初就是指这种物理设备。

tty 在现代 Linux/Unix 中的含义

虽然电传打字机早已被键盘和显示器取代,但 tty 这个术语在操作系统中被保留了下来,用来代表各种形式的终端设备

在 Linux 系统中,tty 可以指代以下几种类型:

  1. 虚拟控制台(Virtual Consoles):当你没有启动图形界面时,按下 Ctrl + Alt + F1F6,你会进入不同的全屏文本模式终端,它们就是虚拟控制台,也叫 tty1tty2 等。

  2. 伪终端(Pseudo-terminals):当你通过 SSH 远程登录云服务器,或者在图形界面中打开一个终端模拟器(比如 GNOME Terminal, Konsole, iTerm2)时,你所使用的就是一种伪终端,通常命名为 pts/0pts/1 等。这里的 pts 就是 Pseudo-terminal Slave 的缩写。

简而言之,tty 是 Linux/Unix 中一个通用的概念,用来表示你与操作系统内核进行交互的接口。无论是直接连接的物理终端,还是远程登录或终端模拟器创建的虚拟终端,它们本质上都是 tty 的现代形式。

grep

grep 的英文全称是 Global Regular Expression Print,意思是“全局正则表达式打印”。这个名字听起来有点复杂,但它的功能其实很直观:在文本中搜索你指定的模式,并把匹配的行打印出来。

  • Global:全局。它会搜索整个输入。
  • Regular Expression:正则表达式。虽然这里你用的是简单的文本字符串,但 grep 支持使用更复杂的模式(正则表达式)进行搜索。
  • Print:打印。它会把匹配到的那一行内容打印到屏幕上。

在你的命令 ps aux | grep "python /data/Avatar/Wan2.2/generate.py" 中,grep 的作用就是:

  1. 接收 ps aux 命令的输出(通过 | 管道符)。
  2. 在这些输出中,逐行搜索是否包含 "python /data/Avatar/Wan2.2/generate.py" 这个字符串。
  3. 如果找到了,就把包含这个字符串的整行内容显示出来。

简而言之,grep 在这里的作用就像一个过滤器,它从一堆杂乱的进程信息中,为你精准地找出了你想要的特定程序。

2. 解决方案:使用 nohup&

为了让程序在我关闭终端后也能继续运行,我需要用到 nohup 命令。

  • nohup (no hang up):这个命令可以防止程序在用户退出终端时被“挂断”(也就是停止)。
  • &:这个符号非常关键,它能将命令放到后台运行,这样我就可以继续在终端中输入其他命令,而不用等待程序结束。

结合这两点,我构建了我的完整命令:

nohup CUDA_VISIBLE_DEVICES=3 PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True python /data/Avatar/Wan2.2/generate.py ... > program_output.log 2>&1 &

这条命令有点长,我来拆解一下:

  • nohup ... &:这是将命令放到后台运行并防止它停止的框架。
  • CUDA_VISIBLE_DEVICES=3:这是一个环境变量,作用是告诉程序,这台机器上虽然可能有多个GPU,但它只能使用编号为3的那一块。这对于防止资源冲突非常重要。
  • PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True:这是PyTorch的环境变量,用于优化GPU显存管理。它告诉PyTorch的内存分配器,如果需要更多内存,可以尝试扩展已有的内存块,这有助于防止显存溢出(OOM)。
  • > program_output.log 2>&1:这是重定向操作。> 将标准输出(STDOUT)重定向到 program_output.log 文件。2>&1 则更进一步,将标准错误输出(STDERR)也重定向到同一个地方。这样,所有日志和错误信息都会被统一保存到这个文件中,方便我日后排查问题。
3. 实时监控程序运行状态

程序在后台运行后,我怎么知道它进行到哪里了呢?答案就在我之前重定向的日志文件里。

我可以使用 tail 命令来实时查看日志文件的更新:

tail -f program_output.log

  • tail:这个命令可以显示文件的末尾内容。
  • -f:这个参数是"follow"的缩写,它会持续监控文件,只要有新内容写入,就会立即显示在终端上。

通过这个命令,我就可以实时看到程序的每一步输出,比如模型加载进度、生成帧数等等,就像程序在前台运行一样。

4. 最终解决的坑:注意命令格式

我在执行 nohup 命令时,曾因为不小心换行,导致终端把 CUDA_VISIBLE_DEVICES=3 当成了一个独立的命令去执行,从而报错 No such file or directory

正确的做法是,确保将所有环境变量、程序命令和重定向操作符都写在同一行,不要有任何换行符。

如果你也遇到类似问题,可以尝试将环境变量单独 export 出来,然后再运行主程序,这样会更保险:

  1. export CUDA_VISIBLE_DEVICES=3
  2. export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
  3. nohup python /data/Avatar/Wan2.2/generate.py ... > program_output.log 2>&1 &

这个方法非常有效,而且 export 的环境变量只对当前终端会话生效,不会影响服务器上的其他进程或用户。如果你需要在另一块GPU上运行新任务,只需在新终端中为它指定不同的设备编号,它们之间不会产生冲突。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐