上一章我们学会了在 linux 上基本的走动和搬东西。现在你写了一个程序——比如一个网站后端、一个机器人、或者一个定时任务——接下来最自然的问题是:怎么让它跑起来,而且关掉终端也不挂?

这看似简单,却是新手最容易踩坑的地方。很多人第一次在服务器上运行程序,一关终端,程序就跟着死了。本章就来讲三种最常见的"让服务活下去"的方式:直接启动、nohup、以及更优雅的 tmuxdocker

直接运行

假设我们有一个脚本 server.py,最简单的方式就是:

python server.py

程序会在前台运行,终端被它占用,你能实时看到它的输出。好处是简单直观,坏处也明显:

  • 终端不能关,一关程序就可能被结束;
  • 终端卡住,没法干别的事。

所以直接运行只适合"临时看一下程序能不能跑"的场景,真正的服务不能这么搞。

nohup

“关掉终端程序就死”,根本原因是终端关闭时会向它启动的子进程发送一个"挂断(HUP)“信号。把程序放到后台,再让它忽略这个信号,就能活下来——这就是 nohup 的用途。

nohup python server.py > output.log 2>&1 &

拆开看:

  • nohup:忽略 HUP 挂断信号;
  • > output.log 2>&1:把程序的正常输出和错误输出都写进 output.log2>&1 表示"错误也归到标准输出去”);
  • &:把程序放到后台运行,终端立刻归还给你。

之后你可以关掉终端,程序仍在运行。想看它在干嘛,就 cat output.logtail -f output.log

想停掉它?用上一章学的 ps aux | grep server.py 找到进程号,再 kill 进程号

nohup 胜在零依赖、一行搞定,适合临时跑个小服务。但它管理起来比较原始——进程号得自己记,日志得自己重定向,重启得手动来。

tmux

如果你希望像在本地一样,随时重新连回那个正在运行程序的"窗口",tmux 是最好的选择。

tmux 是一个终端复用器,它能创建一个"会话(session)",会话里的程序独立于你的登录终端运行。你断开 SSH 连接,会话里的程序照跑不误;下次连上来,把会话"接回来"就行。

常用操作:

  • tmux new -s 名字:新建一个名为"名字"的会话;
  • tmux attach -t 名字:重新接入该会话;
  • 在会话内按 ctrl+b 再按 d: detachment,脱离会话但保持运行(detach);
  • tmux ls:列出所有会话;
  • tmux kill-session -t 名字:关闭某个会话。

典型流程:

tmux new -s myserver     # 新建会话
python server.py         # 在会话里跑程序
ctrl+b 然后 d            # 脱离,程序继续跑
# ... 之后任意时候 ...
tmux attach -t myserver  # 回来看它

tmux 没有 nohup 那种日志重定向的麻烦,你能随时"回到现场"看到实时输出,对新手非常友好。它的缺点是:服务器重启后会话就没了,需要手动重新拉起。

docker

前面几种方式,程序都直接跑在服务器的操作系统上。一旦换台机器、或者环境稍有不同,就可能"在我电脑上能跑"。docker 的思路是:连环境带程序,一起打包成一个"镜像",在哪台机器上都能原样跑

一个最基础的 Dockerfile 长这样(以 Python 为例):

FROM python:3.11-slim      # 基于官方 Python 镜像
WORKDIR /app               # 设定工作目录
COPY . .                   # 把当前目录文件复制进去
RUN pip install -r requirements.txt  # 装依赖
CMD ["python", "server.py"]          # 容器启动时执行的命令

构建并运行:

docker build -t myserver .          # 构建镜像,命名为 myserver
docker run -d -p 8000:8000 myserver # 后台运行容器,把 8000 端口映射出来
  • -d:后台(detached)运行;
  • -p 宿主机端口:容器端口:把容器内的端口暴露到服务器上。

查看与停止:

docker ps            # 看正在运行的容器
docker logs 容器ID    # 看容器日志
docker stop 容器ID    # 停止容器

docker 的优点在于一致性:开发、测试、生产环境完全一致,不用纠结环境问题,这也是正式开发时的规范做法。

该怎么选

  • 临时验证程序对不对:直接前台运行;
  • 临时跑个小服务、懒得装额外东西:nohup ... &
  • 想随时回来看输出、在服务器上长期开发调试:tmux
  • 要交付、要部署、要保证跨机器一致:docker