命令行里的几个小习惯
工具越顺手,人越容易忘记自己在做什么。
一、先分清本地和远端
在服务器上敲命令时,最容易出的错不是语法,而是把本该在远端执行的操作应用到了本地。
我的做法很土但有效:命令写成这样——
ssh myhost 'echo "=== HOST ==="; hostname; cat /etc/os-release | head -3'
引号里的部分一定在远端跑。写完先在心里念一遍「这段在远端」,再回车。
后来发现一个更好的习惯:永远不要用 cd 切换,直接写绝对路径。
# 不要这样
ssh myhost 'cd /var/log && ls'
# 这样更好
ssh myhost 'ls -la /var/log'
切换目录会引入状态,而状态是 bug 的温床。
二、破坏性命令先问
rm -rf 这类命令,原则很简单:先看,再删。
# 先看清楚要删什么
ls -la /path/to/dir
# 用 trash 代替 rm(如果系统有)
trash /path/to/file
如果实在没有 trash 工具,至少把路径先 echo 出来看一眼:
echo "我要删除: /var/log/app/*.log"
多这一秒,能省掉很多事。
三、别相信「连上了」
建立连接成功不等于服务正常。判断一个端口是否真的在监听,不能只看 TCP 能不能连上——
有些代理会接受所有本地连接。一个不存在的端口也会「连接成功」。
可靠的办法是协议握手:
# SSH 应该返回 banner
timeout 5 nc -v host 22 </dev/null
# HTTPS 应该返回 TLS 握手
timeout 5 openssl s_client -connect host:443 </dev/null
拿到 banner 才算真的通了。
四、写操作要回读
远程执行了写操作,不代表它成功了。读回来看一眼才算。
# 写入
echo 'foo' > /tmp/test.conf
# 回读验证
cat /tmp/test.conf
更严格的做法是连属主和权限一起看:
ls -l /tmp/test.conf
五、把不确定的东西标出来
做诊断时最容易犯的错,是给出一个自己没测过的因果解释。
比如「你的请求是直接连的,为什么会经过 DNS 解析?」——这种反问非常合理,而且往往说明你的解释里有个没验证的环节。
所以规矩是:没测过的机制,不要命名。
- 「我猜是防火墙拦的」和「抓包显示没有 RST 也没有 ICMP unreachable,所以是 DROP」——后者才是能站住的结论
- 「应该是这个原因」和「我做了 A/B 测试,切换后现象消失」——后者才叫证据
区分「相关」和「因果」,唯一的办法是找一个能区分两个假设的测量。找不到,就直说不知道。
承认不知道,比给出一个听起来很专业的错误结论便宜得多。
六、工具会变,习惯不会
上面这些没什么技术含量。但换了语言、换了系统、换了云厂商,这些原则仍然成立。
真正需要长期积累的,不是某个命令的用法,而是对系统状态保持怀疑的那种习惯。