这一篇讲什么
连载的最后一篇。前半部分是几个天天用、却经常用错的基础操作;后半部分把前八篇实测过的报错汇总成一张表,按报错原文查原因。
机器:CentOS 7.9(VMware)、Rocky 9.8、Ubuntu 24.04.5(后两台是 LXD 虚拟机,cloud 镜像)。
1. sudo echo > /etc/xxx:权限不够 ✅
普通用户有 sudo 权限(NOPASSWD),往 /etc 下写文件:
bash
-bash: line 1: /etc/lab9_a.txt: Permission denied
sudo echo > 退出码=1
| sudo tee 退出码=0
/etc/lab9_b.txt
(Rocky 9 / Ubuntu 24.04;CentOS 7 那台是中文「权限不够」。)sudo echo hello > /etc/lab9_a.txt 里,重定向 > 是当前 shell(普通用户)做的 ,sudo 只管到 echo。正确写法:
bash
echo hello | sudo tee /etc/lab9_b.txt >/dev/null
追加用 sudo tee -a。
2. 脚本就在当前目录,却 command not found ✅
arduino
-bash: line 1: hi.sh: command not found
ok
hi.sh 找不到,./hi.sh 输出 ok。当前目录不在 PATH 里,要写 ./。三台一样(CentOS 7 是「未找到命令」)。
3. 普通用户绑不了 80 端口 ✅
ini
socket.error: [Errno 13] Permission denied (CentOS 7,python2)
PermissionError: [Errno 13] Permission denied (Rocky 9 / Ubuntu 24.04)
net.ipv4.ip_unprivileged_port_start = 1024
1024 以下的端口只有 root 能绑。新内核有 ip_unprivileged_port_start 这个参数可以调;CentOS 7 的内核没有它:
bash
sysctl: cannot stat /proc/sys/net/ipv4/ip_unprivileged_port_start: No such file or directory
4. 2>&1 写在前面,错误照样打到屏幕上 ✅
bash
ls: cannot access '/nonexist': No such file or directory
2>&1 写前面:屏幕上看到上面那行,文件里 0 行
2>&1 写后面:文件里 1 行:ls: cannot access '/nonexist': No such file or directory
三台一样。
ls /nonexist 2>&1 > o1.txt:先把 stderr 指向「stdout 当前指向的地方」(屏幕),再把 stdout 改到文件 ------ stderr 还是屏幕;ls /nonexist > o2.txt 2>&1:先把 stdout 改到文件,再让 stderr 跟着 stdout ------ 都进文件。
重定向从左往右依次生效,2>&1 放最后。 nohup java -jar app.jar > app.log 2>&1 & 是对的写法。
5. cat a.log > a.log:文件被清空 ✅
lua
cat a.log > a.log 之后:0 字节
cat: a.log: input file is output file (CentOS 7)
Rocky 9 / Ubuntu 24.04 连这句提示都没有,安静地清空 。shell 先处理 > a.log(把文件截断成 0),然后 cat 才去读 ------ 已经没东西可读了。同一个文件既读又写,都是这个结果。要写回原文件,先写到临时文件再 mv,或者用 sed -i (但注意第八篇讲的 sed -i 会破坏软链)。
6. 防止 > 误覆盖:noclobber ✅
arduino
noclobber 下 > 退出码=1
keep
forced
bash: line 1: k.txt: cannot overwrite existing file
三台一样。set -o noclobber 之后,> 不会覆盖已存在的文件(keep 还在);确实要覆盖时用 >|(写进了 forced)。可以放进自己的 ~/.bashrc,防手滑。
7. ls -l 的时间:老文件不显示时分 ✅
yaml
Sep 21 17:46 new.txt
Jan 15 2025 old.txt
2025-01-15 10:30:00.000000000
三台一样。较早的文件(这里是 2025 年 1 月),时间列从「时:分」变成了「年份」;看精确时间用 ls -l --full-time(第三行)。写脚本别去解析 ls -l 的时间列。
8. 通配符是 shell 展开的,不是命令 ✅
bash
rm a.log x.log y.log
ls: cannot access '*.xyz': No such file or directory
没匹配时 echo *.xyz 输出:*.xyz
- 第一行:
echo rm *.log------*.log在命令执行之前就被 shell 换成了文件列表。执行危险的rm *之前,先把rm换成echo rm看一眼实际要删什么。 - 没有匹配的文件时,bash 把
*.xyz原样 传给命令。ls报找不到一个叫*.xyz的文件;如果这个命令是rm -f *.xyz,就会静默什么都不做。
9. man 有好几份:crontab(1) 和 crontab(5) ✅
bash
/usr/share/man/man1/crontab.1.gz
/usr/share/man/man5/crontab.5.gz
(CentOS 7。)man crontab 默认打开第 1 节(命令怎么用);crontab 文件的格式在第 5 节,要 man 5 crontab。两台 LXD 虚拟机是 cloud 镜像,没装 man。
10. 时间和时区 ✅
yaml
Local time: Tue 2026-09-22 01:46:53 CST
Time zone: Asia/Shanghai (CST, +0800)
NTP synchronized: yes
chronyd active (CentOS 7)
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
systemd-timesyncd active (Ubuntu 24.04)
同步时间的服务不一样:CentOS 7 用 chronyd,Ubuntu 用 systemd-timesyncd。cloud 镜像的时区默认是 UTC,日志时间比北京时间差 8 小时 ------ 第六篇、第三篇里 LXD 两台的日志时间都是 UTC。Rocky 9 cloud 镜像里两个同步服务都没有:
yaml
System clock synchronized: no
NTP service: n/a
11. 服务明明起来了,别的机器连不上 ------ 看监听地址 ✅
Ubuntu 上起两个服务,8081 只监听 127.0.0.1,8082 监听 0.0.0.0,防火墙是关的:
makefile
127.0.0.1:8081
0.0.0.0:8082
Status: inactive
从 Rocky 9 去连:
yaml
bash: line 1: /dev/tcp/10.115.180.200/8081: Connection refused
8081 端口退出码=1
8082 端口退出码=0
防火墙关着,照样 Connection refused。 本机 curl 127.0.0.1:8081 是通的,于是很多人去查防火墙、查安全组,查半天。先 ss -lnt 看一眼监听地址:是 127.0.0.1 就只有本机能连,要改程序的监听地址(Java 应用常见的 server.address、各种 bind 配置)。
12. 报错速查表(汇总全部九篇)
按你看到的报错原文,找到原因和对应篇目。 每一条都是本连载在 CentOS 7.9 / Rocky 9.8 / Ubuntu 24.04.5 上实际复现过的。
网络 / 端口
| 报错原文 | 原因 | 篇 |
|---|---|---|
No route to host(立刻返回) |
firewalld 在拒绝,不是路由问题 | 二、五 |
Connection refused |
对端没监听这个端口,或者只监听了 127.0.0.1,或者触发了 ufw 的 limit 规则 | 二、九 |
连接超时(Ncat: TIMEOUT.) |
包被丢了,实测是 Ubuntu 的 ufw 默认策略 | 二 |
Bind to port 2222 on 0.0.0.0 failed: Permission denied. |
SELinux 不允许 sshd 绑这个端口 | 五 |
改了 SSH 端口,ss 里还是只有 22(Ubuntu 24.04) |
socket 激活,要 daemon-reload + 重启 ssh.socket |
五 |
kex_exchange_identification: read: Connection reset by peer |
OpenSSH 9.8+ 的 PerSourcePenalties,认证失败太多被临时封 | 五 |
Permission denied (publickey,...) |
看服务端日志 Authentication refused: bad ownership or modes |
五 |
REMOTE HOST IDENTIFICATION HAS CHANGED! |
对端主机密钥变了(重装),ssh-keygen -R |
五 |
cannot create /dev/tcp/...: Directory nonexistent |
脚本用的是 sh(Ubuntu 上是 dash) | 五 |
ping: local error: message too long, mtu=1500 |
包超过 MTU | 五 |
软件源
| 报错原文 | 原因 | 篇 |
|---|---|---|
Cannot find a valid baseurl for repo |
CentOS 7 官方源已下线,要换 vault 镜像 | 一 |
403 Forbidden(vault.centos.org) |
国内直连官方 vault 被拒,换国内镜像站的 centos-vault | 一 |
No matching repo to modify: powertools |
Rocky 9 里它叫 crb |
一 |
Could not get lock /var/lib/dpkg/lock-frontend |
另一个进程拿着 dpkg 的锁,报错里写了是哪个进程 | 一 |
服务 / 定时任务
| 报错原文 | 原因 | 篇 |
|---|---|---|
status=203/EXEC |
systemd 连程序都没执行起来:路径不对、没有执行权限 | 三 |
Executable path is not absolute |
ExecStart 必须写绝对路径 | 三 |
start-limit-hit / Start request repeated too quickly |
短时间重启太多次被 systemd 拦下 | 三 |
NeedDaemonReload=yes / 改了 unit 不生效 |
没 systemctl daemon-reload |
三 |
getpwnam() failed |
/etc/cron.d/ 里的行少写了「用户名」那一列 |
三 |
No MTA installed, discarding output |
cron 的输出没地方发,被丢了 | 三 |
unexpected EOF while looking for matching |
crontab 里的 % 没转义 |
三 |
磁盘
| 报错原文 | 原因 | 篇 |
|---|---|---|
df 满了,du 找不到 |
文件已删但进程还开着,lsof +L1 |
四 |
No space left on device,df -h 却没满 |
inode 用尽,看 df -i |
四 |
target is busy |
有进程在用这个挂载点 | 四 |
Give root password for maintenance |
fstab 写错,开机进了紧急模式 | 四 |
Timed out waiting for device |
fstab 里的设备不存在(加了 nofail 能开机,但要多等 90 秒) |
四 |
unrecognized option '--verify' |
CentOS 7 的 findmnt 没有 --verify |
四 |
shrinking is unsupported |
xfs 不能缩小 | 四 |
日志 / 性能
| 报错原文 | 原因 | 篇 |
|---|---|---|
no persistent journal was found |
没有 /var/log/journal,journal 重启就丢 |
六 |
dmesg: read kernel buffer failed: Operation not permitted |
Ubuntu 的 dmesg_restrict = 1 |
六 |
| 进程退出码 137 | 被 SIGKILL,多半是 OOM,dmesg 里找 killed process |
六 |
cannot stat /proc/sys/net/ipv4/tcp_tw_recycle |
新内核已删除这个参数 | 六 |
用户 / 权限 / 文件
| 报错原文 | 原因 | 篇 |
|---|---|---|
sudo: a password is required(明明配了 NOPASSWD) |
sudoers.d 里的文件名带了 . |
七 |
no valid sudoers sources found, quitting |
sudoers.d 里有语法错误的文件(CentOS 7 上 sudo 全挂) | 七 |
文件 644 却 Permission denied |
路径上某层目录没有 x,namei -l |
七 |
-????????? |
目录有 r 没有 x | 七 |
Operation not permitted(root 删文件) |
文件有 chattr +i 属性 |
七 |
Operation not permitted(普通用户删别人的文件) |
目录有粘滞位(drwxrwxrwt) |
七 |
parameter null or not set |
${VAR:?} 保护生效了,变量是空的 |
七 |
bad interpreter: No such file or directory / cannot execute: required file not found |
脚本是 Windows 的 CRLF 换行 | 八 |
can't read s/a/b/: No such file or directory |
照抄了 macOS 的 sed -i '' |
八 |
tar: x.tgz: Cannot stat + 多了个叫 z 的文件 |
tar -cfz,-f 要放最后 |
八 |
gzip: invalid option -- 'k' |
CentOS 7 的 gzip 1.5 没有 -k |
八 |
unknown option -- O(scp) |
CentOS 7 的 scp 没有 -O |
八 |
cannot overwrite existing file |
开了 noclobber,强制覆盖用 `> | ` |
权限不够(sudo echo > 文件) |
重定向不归 sudo 管,用 sudo tee |
九 |
连载目录
- 换源:CentOS 7 停更后 yum 怎么用
- 防火墙与端口:firewalld / ufw / iptables / SELinux
- systemd 服务与 cron
- 磁盘:空间、inode、LVM、fstab
- 网络与 SSH
- 日志与性能
- 用户与权限
- 文本处理、压缩与传输
- 基础命令的坑 + 报错速查表(本篇)
全部在同样的三台机器上实测:CentOS 7.9、Rocky 9.8、Ubuntu 24.04.5。