Linux Day31——实操启停服务改端口重启


type: note

title: Linux:起服务、停服务、改端口重启

date: 2026-11-04

description: 用普通用户起一个 Python HTTP 服务、日志落盘、后台运行;用 ps 找 PID、kill 停干净、ss 确认端口消失;换 8080 端口重启并验证。含分层定位的旧知识回收

tags: Linux, 进程, 服务, 试点


Linux:起服务、停服务、改端口重启

> 📌 GitHub:https://github.com/AR-firefly

笔记区

核心观点

**1. 起服务就是三件事**

一条命令要同时做到三样,才叫「起了一个真服务」:

| 要什么 | 靠什么 |

| ---------------------- | --------------- |

| 在后台跑,不占着终端 | 命令末尾加 `&` |

| 输出(含报错)落进文件 | `> 文件名 2>&1` |

| 在指定端口等人来连 | 命令里写端口号 |

`&` 是放到后台:敲完提示符立刻回来,程序继续跑。

`>` 是把正常输出写进文件,不显示在屏幕上。

`2>&1` 是把报错那股(`2`)并到正常输出那股(`&1`),两股合成一股一起进文件。

少了 `2>&1` 不是看不到报错,而是报错**只打在终端上、不进日志文件**------事后翻日志什么都看不到。

**2. 服务活着的硬判据:端口在 LISTEN**

`ss -lnt` 的输出里,`Local Address:Port` 那一列出现目标端口、`State` 是 `LISTEN`,才说明内核那边有人在等连接。

`0.0.0.0:8080` 表示绑在所有网卡上,本机用 `127.0.0.1:8080` 和 `172.17.158.107:8080` 都能连到。

**3. 停服务要认 PID,不能关终端**

  • 关终端是对**这个终端里所有进程**下手,服务只是其中之一

  • 用 `nohup` 起的服务,关终端反而不死,以为停了其实还在跑

  • 认准 PID 再 `kill`,才是只打这一个

`kill` 之后终端会打印 `1+ Terminated ...`,但那只是作业结束的提示,**不能当停干净的证据**。要用 `ss -lnt` 或 `ps` 再确认一次。

**4. `ps` 不带参数只看两样少的东西**

| 命令 | 列哪些进程 | `CMD` 列显示什么 |

| -------- | ---------- | ---------------------------------------- |

| `ps` | 只当前终端 | 只有命令名 `python3` |

| `ps -e` | 所有进程 | 只有命令名 `python3` |

| `ps -f` | 只当前终端 | 完整命令行 `python3 -m http.server 8000` |

| `ps -ef` | 所有进程 | 完整命令行 |

所以拿 `ps | grep 'python3 -m http.server'` 什么都筛不到------不带 `-f` 时那列只有 `python3`,后面那串参数根本没显示。

`-e` = every(所有进程),`-f` = full(完整格式)。`-f` 补出来的列有:`UID`(属主)、`PPID`(父进程)、`C`(CPU 占比)、`STIME`(启动时间)。

**5. 日志一行怎么读**

`127.0.0.1 - - 04/Nov/2026 20:01:59 "HEAD / HTTP/1.1" 200 -`

读成一句话:**谁、什么时候、用什么方法要什么、结果怎样**。

| 片段 | 意思 |

| ------------------- | --------------------------------------------- |

| `127.0.0.1` | 谁来的 |

| `- -` | 两个占位(身份、用户名),HTTP 不带这两个信息 |

| `时间` | 什么时候 |

| `"HEAD / HTTP/1.1"` | 方法 + 路径 + 协议版本 |

| `200` | 结果,成功 |

| `-` | 回给对方的字节数,`HEAD` 不要正文所以是横杠 |

**6. 地址四段**

`http://127.0.0.1:8000/\` 拆成:协议 / 主机 / 端口 / 路径。

  • `127.0.0.1` 是本机回环,**只有本机能访问**

  • `172.17.158.107` 是网卡地址,**同一网络的其他机器能找到**

  • 端口要写服务实际监听的那个,改 8080 地址就得跟着改

  • `80` 是 HTTP 默认端口,但 **1024 以下只有 root 能监听**,普通用户只能挑 1024 以上

**7. `http.server` 和 `curl` 是两头**

| 角色 | 谁 | 干什么 |

| ------ | ------------- | ------------------------------------ |

| 服务端 | `http.server` | 开店:在端口上等连接,有人来了就回应 |

| 客户端 | `curl` | 顾客:主动上门敲门,看有没有人应 |

服务端不会自己敲自己的门,所以验证「店开没开」必须另起一个客户端。浏览器同样能当这个客户端。

关键方法/流程

**起服务**

| 步 | 命令 | 判据 |

| --- | ------------------------------------------------- | ----------------------------------- |

| 1 | `mkdir -p ~/lab/d1` | 目录存在(`-p` 让它已存在也不报错) |

| 2 | `cd ~/lab/d1` | `pwd` 显示 `/home/ar-26710/lab/d1` |

| 3 | `python3 -m http.server 8000 > server.log 2>&1 &` | 打印 `1 <PID>`,提示符立刻回来 |

| 4 | `curl -I http://127.0.0.1:8000/\` | 第一行 `HTTP/1.0 200 OK` |

| 5 | `cat server.log` | 有一行访问记录 |

**停服务**

| 步 | 命令 | 判据 |

| --- | ---------------------------- | ------------------------------------------------- |

| 1 | `ps -ef \| grep http.server` | 找到 `python3 -m http.server 8000` 那行,记下 PID |

| 2 | `kill <PID>` | 终端打印 `Terminated` |

| 3 | `ss -lnt` | 端口不在列表里 |

**改端口重启**

同一个流程,三处一起改:起服务命令里的端口、访问地址里的端口。日志文件名如果也换(`server.log` → `app.log`),重定向那里一并改。

实战记录

**记录 1:起服务**

```

1 1282

```

`1` 是作业号(Shell 编的),`1282` 是 PID(内核编的)。提示符立刻回来,说明 `&` 生效。

**记录 2:kill 之后**

```

1+ Terminated python3 -m http.server 8000 > server.log 2>&1

```

**记录 3:换成 8080 之后**

```

HTTP/1.0 200 OK

Server: SimpleHTTP/0.6 Python/3.14.4

Content-type: text/html; charset=utf-8

Content-Length: 340

```

`ss -lnt` 的最后一行:`LISTEN 0 5 0.0.0.0:8080 0.0.0.0:*`

**记录 4:`app.log` 里的访问记录**

```

127.0.0.1 - - 04/Nov/2026 20:01:59 "HEAD / HTTP/1.1" 200 -

```

服务起不来的三类原因(2026-11-05 补)

**判据总表**

| 类型 | 报错首词 | 进程状态 | 日志文件 | 第一步查 | 修 |

| ---------- | ------------------------ | ------------------- | ---------------------- | ------------------ | --------------- |

| 路径不存在 | `bash:` | 立刻 `Exit 1` | 没建出来 | 报错点名的那个路径 | `mkdir -p` |

| 没写权限 | `bash:` | 立刻 `Exit 1` | 没建出来 | 属主 + 权限位 | `chmod u+w` |

| 端口被占 | `Traceback` / `OSError:` | 跑了一段才 `Exit 1` | 建出来了,报错写在里面 | 谁占着端口 | `kill` 或换端口 |

**怎么分类:看报错首词**

  • `bash:` 开头 = **shell** 报的 = 命令没跑(卡在重定向那一步)

  • `Traceback` / `OSError:` 开头 = **程序自己**报的 = 跑起来了才撞墙

**第二个判据:`N PID` 后面跟什么**

起服务时 `&` 会先分配 PID,所以 `N 数字` 一定会打印。区别在下一行:

  • 紧跟 `N+ Exit 1` = 进程已经退出

  • 没有 `Exit` = 还活着

**1. 路径不存在**

  • 命令:`python3 -m http.server 8000 > logs/app.log 2>&1 &`

  • 现象:`bash: logs/app.log: No such file or directory` + `2+ Exit 1`

  • 机制:shell 先打开 `>` 后面那个文件,打不开就不执行后面的命令

  • 修:`mkdir -p logs`

**2. 没写权限**

  • 现象:`bash: logs_ro/app.log: Permission denied`

  • 权限 10 位 = `d` + 三组 `rwx`(属主 / 同组 / 其他人)

  • `dr-xr-xr-x` = 目录,属主 `r-x`(**没有 w**),同组 `r-x`,其他人 `r-x`

  • **目录的 `w` 管「能不能在里面新建、删除、改名文件」**;属主没有 `w`,自己照样写不进去

  • 修:`chmod u+w 目录`(`u` 属主、`+` 加、`w` 写)

**3. 端口被占**

  • 现象:`Traceback ... OSError: Errno 98 Address already in use`

  • 程序跑起来了,走到 bind(绑端口)那一步才失败

  • 查占用者:`ss -lntp | grep :端口`,输出 `users:(("python3",pid=NNN,fd=3))`

  • 认人:`ps -p NNN -o pid,cmd`

  • 修:`kill NNN`,或者换端口

  • `Errno 98` 是系统给「地址被占」编的号

**Traceback 怎么读**

  • `Traceback (most recent call last)` = 回溯,越往下越接近真凶

  • 中间一行行 `File "...", line N, in 函数名` = 调用链

  • **最后一行 = 真正的原因**

**`2>&1` 在这类故障里的后果**

报错被送进日志文件,**屏幕上什么都看不到**,只有一个 `N PID`。看着像成功,其实已经死了。`cat 日志文件` 才看得到。


线索区(学完后合上材料,自问自答)

**Q: 起服务那条命令里,`&` 和 `2>&1` 各干什么?少了会怎样?**

A: `&` 放后台,少了要一直占着终端;`2>&1` 把报错并进正常输出那股,少了报错只打在终端上、不进日志文件。

**Q: 怎么判断一个服务真的停了?**

A: `ss -lnt` 里端口不在列表里。`kill` 后终端打印的 `Terminated` 不算证据。

**Q: 为什么 `ps | grep 'python3 -m http.server'` 什么都筛不到?**

A: 不带 `-f` 时 `CMD` 列只写命令名 `python3`,后面的参数不显示。

**Q: `ps -e` 和 `ps -f` 分别补什么?**

A: `-e` 补范围(所有进程,不只当前终端);`-f` 补格式(完整命令行 + `UID` / `PPID` / `C` / `STIME`)。

**Q: 日志一行 `127.0.0.1 - - 时间 "HEAD / HTTP/1.1" 200 -` 怎么读?**

A: 谁来的 / 两个占位 / 时间 / 方法+路径+协议 / 状态码 200 / 回包字节数(HEAD 无正文所以是横杠)。

**Q: `http://127.0.0.1:8000/\` 四段各是什么?为什么不用 80?**

A: 协议 / 主机 / 端口 / 路径。`127.0.0.1` 是本机回环,只有本机能访问。80 是默认端口但 1024 以下要 root。

**Q: `curl` 和 `http.server` 各是什么角色?**

A: `curl` 是客户端(去敲门),`http.server` 是服务端(在端口上等着)。服务端不会自己敲自己的门。

**Q: 为什么停服务要用 PID 而不是关终端?**

A: 关终端会杀掉这个终端里所有进程,而且 `nohup` 起的服务关终端不死,以为停了其实还在跑。

**Q: 起服务后终端只回了 `2 4256`,没报错,怎么判断它死没死?**

A: 看下一行有没有 `2+ Exit 1`。有 = 已经退出;没有 = 还活着。再配合 `ss -lnt` 看端口在不在。

**Q: `bash: xxx: No such file or directory` 和 `bash: xxx: Permission denied` 怎么分?**

A: 都是 shell 报的、命令都没跑。一个说路径不存在,一个说路径在但没权限。分别查路径、查属主和权限位。

**Q: 什么情况下报错会变成 `Traceback`?**

A: 程序真的跑起来了,运行中撞墙。比如端口被占,走到 bind 那一步才失败。

**Q: 端口被占,怎么找到占用者?**

A: `ss -lntp | grep :端口` 看 pid,`ps -p PID -o pid,cmd` 认人,再决定 kill 还是换端口。


总结(50字以内,用自己的话概括今天学到了什么)

起服务三样:后台跑、日志落文件、端口在听;停要认 PID,停完看 LISTEN;改端口地址跟着改。


复习卡片

| 概念 | 必学/了解 | 一句话 | 场景 |

| ------------------------ | --------- | ------------------------------------------------------- | ------------------ |

| `&` | 必学 | 命令末尾加 `&`,程序放后台,提示符立刻回来 | 起服务不占终端 |

| `>` | 必学 | 正常输出写进文件,不显示在屏幕上 | 日志落盘 |

| `2>&1` | 必学 | 报错那股并到正常输出那股,一起进文件 | 报错也要留在日志里 |

| `ps -ef` | 必学 | `-e` 所有进程、`-f` 完整命令行(含参数) | 找进程号 |

| `kill` | 必学 | 给指定 PID 发信号,默认终止 | 停服务 |

| `ss -lnt` | 必学 | 列出所有在监听的 TCP 端口,`LISTEN` 才算活着 | 判断服务在不在跑 |

| `curl -I` | 必学 | 发 HEAD 请求,只要响应头 | 验证服务回不回话 |

| `nohup` | 了解 | 挂断/关终端时不杀它;`man 1 nohup` | 长期跑的服务 |

| `pgrep` | 了解 | 按名字找进程,比 `ps \| grep` 少一条管道;`man 1 pkill` | 快速找 PID |

| `ss -lntp` | 了解 | 加 `-p` 显示进程名,要 `sudo`;`man 8 ss` | 看端口被谁占 |

| `Exit 1` | 必学 | 进程退出时留的状态码,0 正常、非 0 出错 | 判断进程死没死 |

| `Permission denied` | 必学 | 路径在,但当前身份没权限 | 日志写不进去 |

| `Address already in use` | 必学 | 字面:地址已被占用;常跟 `Errno 98` | 端口被占 |

| `Errno 98` | 必学 | `Err` 错误 + `no` 编号;98 专门绑「地址被占」 | 端口被占 |

| `chmod u+w` | 必学 | 改模式:`u` 属主、`+` 加、`w` 写 | 补目录写权限 |

| `Traceback` | 必学 | Python 报错的开头,越往下越接近真凶 | 分清「程序撞墙」 |


流程附加段

旧知识回收

| 概念 | 一句话 | 出处 |

| ----------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------- |

| 四层各管什么 | 链路(这一小段路)/ 网络(IP 找路)/ 传输(敲门、送全)/ 应用(门开了说什么)。一开始把「连不上」答成应用层 | 复习第 1 问 |

| 分层的好处 | 不是「某层出错不影响别的」(底层断上面全废),是「换掉一层技术不用重写别的层」 | 复习第 2 问 |

| MAC 与 IP | 网卡自己的 MAC 全程不变;每一跳换的是**帧头里写的下一个接手人**。IP 是收件地址,一路不变 | 复习第 3 问 |

| `addr` vs `link` | `addr` 看地址(IP / IPv6),`link` 看网卡本身(状态、MAC、标志位)。`link` 里没有任何地址 | 复习第 4 问 |

| `ip route get` 的 `via` | **有 `via` = 交给下一跳中转 = 不同网段;没有 `via` = 直达 = 同网段** | 11-05 复习 |

| 两个地址判同段 | 必须带掩码。同一对地址,`/20` 下可能同段,`/24` 下可能就不同段 | 11-05 复习 |

| shell 与 `python3` | shell 是终端里读命令的那一层;`python3 -c "..."` 是让 shell 启动 python3 程序去跑代码。`-c` 是 python3 自己的选项 | 11-05 追问 |

今日产出验收

| 产出条 | 证据 | 结果 |

| ------------------------------ | ----------------------------------------------------- | ---- |

| 一个跑在 8080 的服务 | `ss -lnt` 最后一行 `0.0.0.0:8080`、`curl -I` 拿到 200 | 过 |

| 日志落在 `~/lab/d1/app.log` | `cat app.log` 有一行 `HEAD / HTTP/1.1" 200` | 过 |

| 说清停、起、换端口各用哪条命令 | 复盘三问答出 | 过 |

| 说清凭什么判断停干净了 | 「`ss -lnt` 里端口不在列表里」 | 过 |

| 分清三类起不来(11-05) | 报错首词 `bash:` vs `Traceback`;`Exit 1` 判据 | 过 |

| 独立排查一次端口被占(11-05) | 自己拼出 `grep 8000` / `kill` / 起服务 / `curl`,200 | 过 |

相关推荐
百度Geek说1 小时前
QCon上海2026:百度 SRE Agent 规模化落地实践解读
运维·自动化运维
叼烟扛炮1 小时前
Linux 学习笔记(五十八):IO 多路复用封神——epoll 底层原理揭秘
linux·运维·服务器·网络·笔记·学习·php
叼烟扛炮1 小时前
Linux 学习笔记(五十一):数据链路层与 ARP 协议——局域网寻址与黑客骗局
linux·网络·网络协议·php·tcpdump
星恒随风2 小时前
Linux网络编程:彻底理解IO多路复用select!从fd_set位图、读写就绪到手写TCP多客户端字典服务器
linux·服务器·网络
陈布衣2 小时前
MySQL(1)_MySQL 5.7.21 Linux 安装笔记
linux·笔记·mysql
分布式存储与RustFS4 小时前
给 RustFS 桶加一层内存缓存:用 Alluxio 让热数据少跑一遍网络
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
Oiiouui4 小时前
linux服务器部署Logto后端与对应前端的实现
linux·服务器·前端·后端
ITKEY_5 小时前
用 Emacs Dired 实现 em:退出文件管理器后,让终端自动切换目录
linux·服务器·emacs