--- id: devops.linux.commands title: 常用命令:文件、文本处理、进程、端口、权限、systemd type: lesson domain: devops stack: [linux] tags: [grep, awk, ps, ss, chmod, systemd, journalctl] level: basic est_hours: 3 related: [devops.linux.troubleshooting, devops.linux.interview] week: [14] order: 1 --- # 常用命令:文件、文本处理、进程、端口、权限、systemd ## 解释说明 | 类别 | 命令 | 常用写法 | | --- | --- | --- | | 文件 | `ls` `cd` `cp` `mv` `rm` `find` | `find /var/log -name "*.log" -mtime +7`(7 天前的日志) | | 查看 | `cat` `less` `head` `tail` | `tail -f app.log`(实时跟踪)、`tail -n 200 app.log` | | 文本 | `grep` `awk` `sort` `uniq` `wc` `sed` | `grep -n "ERROR" app.log`、`awk '{print $1}'`(取第一列) | | 进程 | `ps` `top` / `htop` `kill` `pgrep` | `ps -ef | grep api`、`kill -15 PID`(先礼后兵,最后才 `-9`) | | 端口 / 网络 | `ss` `curl` `ping` `dig` | `ss -lntp`(谁在监听哪个端口)、`curl -v http://127.0.0.1:8080/healthz` | | 磁盘 | `df` `du` | `df -h`、`du -sh /var/log/* | sort -h` | | 权限 | `chmod` `chown` `sudo` | `chmod 600 .env`、`chown app:app /srv/app -R` | | 服务 | `systemctl` `journalctl` | `systemctl status api`、`journalctl -u api -f` | | 传输 | `scp` `rsync` `ssh` | `rsync -avz dist/ user@host:/srv/web/` | **权限**:`rwx` 分别对应 4、2、1;`chmod 755` = 所有者 rwx、组和其他人 r-x。密钥文件用 `600`。服务不要用 root 运行,单独建一个用户。 **管道和重定向**:`|` 把前一个命令的输出交给后一个;`>` 覆盖写文件、`>>` 追加;`2>&1` 把错误输出也合并进来。 **systemd**:把程序注册成系统服务——开机自启、崩溃自动重启、日志统一交给 journald。 ## 案例 - 统计访问日志里请求最多的 10 个 IP:`awk '{print $1}' access.log | sort | uniq -c | sort -rn | head`。 - 统计 5xx 的数量:`awk '$9 >= 500' access.log | wc -l`(combined 格式第 9 列是状态码)。 - 找出占用 8080 端口的进程:`ss -lntp | grep 8080`。 - Go API 部署成 systemd 服务,崩溃 3 秒后自动重启,日志用 `journalctl -u api` 查看。 ## 代码示例 文本处理组合(可以对 [examples/log-analysis/sample_access.log](examples/log-analysis/sample_access.log) 直接运行): ```bash # 状态码分布 awk '{print $9}' sample_access.log | sort | uniq -c | sort -rn # 请求最多的 IP awk '{print $1}' sample_access.log | sort | uniq -c | sort -rn | head -n 3 # 耗时超过 1 秒的请求(最后一列是 $request_time) awk '$NF > 1 {print $NF, $7}' sample_access.log | sort -rn # 某个时间段的错误 grep '23/Oct/2026:10:00' sample_access.log | grep -E '" 5[0-9]{2} ' ``` 同样的分析用 Python 写成脚本:[examples/log-analysis/analyze.py](examples/log-analysis/analyze.py)。 Go 服务的 systemd 单元文件 `/etc/systemd/system/api.service`: ```ini [Unit] Description=Order API After=network-online.target Wants=network-online.target [Service] User=app Group=app WorkingDirectory=/srv/api EnvironmentFile=/srv/api/.env ExecStart=/srv/api/bin/api Restart=on-failure RestartSec=3 # 停止时先发 SIGTERM,等 15 秒再强杀 TimeoutStopSec=15 LimitNOFILE=65535 [Install] WantedBy=multi-user.target ``` ```bash sudo systemctl daemon-reload # 修改单元文件后必须执行 sudo systemctl enable --now api # 开机自启并立即启动 systemctl status api journalctl -u api -f --since "10 min ago" ``` ## 易错点 - **`kill -9` 当默认**:进程来不及清理(关闭连接、写完文件)。先 `kill`(SIGTERM),等不及再 `-9`。 - **`rm -rf $DIR/` 变量为空**:变成 `rm -rf /`。脚本里加 `set -u`,或写 `"${DIR:?}"/`。 - **删除正在被写的大日志文件**:空间不释放(进程还持有文件句柄)。用 `: > app.log` 清空,或者重启进程;配置 logrotate。 - **`chmod 777` 解决权限问题**:安全隐患。找出正确的用户和组。 - **修改 systemd 单元文件后忘了 `daemon-reload`**:改动不生效。 - **在服务器上直接 `vim` 改线上配置不留记录**:配置纳入 Git,通过部署流程发布。 ## 面试常问 见 [Linux 面试题](interview.md):查端口占用、查日志、统计、软链接和硬链接、进程信号。