Linux、Nginx入门到进阶W1
第一周入职、第一次上跳板机、第一次接生产服务器,最让人头大的不是不会用 Linux,而是「不知道该背哪些命令」。man 手册一打开几千行,每条命令二三十个参数,背完一遍隔天忘九成。
这篇按自己工作里实际使用频率重排:把命令按「在哪儿 / 看什么 / 改什么 / 联网 / 进程」五类归档,每个都给一两条真实能跑的例子。背熟这一篇,新人第一周上服务器干活完全够用。
一、心智模型:按「干什么」归档,不要按字母背
很多教程把命令按字母排:awk → cat → cd → chmod → ...,看着齐整,实际用的时候根本想不起来。
我自己平时排查问题的思路是这样:
打开终端 │ ├─→ 我在哪儿? pwd ls cd find │ ├─→ 我要看什么? cat less tail grep │ ├─→ 我要改什么? touch cp mv rm chmod │ ├─→ 联网能不能通? ping curl ss ssh │ └─→ 进程跑没跑? ps top kill nohup
这五个分类基本就是日常工作的全部,剩下的压缩、归档、帮助系统加一起也就再多 5-6 个命令。先把这 30 个练到肌肉记忆,再去补长尾。
二、在哪儿(目录定位)
pwd / ls / cd:最最基础的三件套
pwd# 我现在在哪个目录ls# 当前目录下有什么ls -lah # 长格式 + 隐藏文件 + 人类可读大小(最常用组合)ls -lt # 按修改时间倒序,调试时找最新文件用cd /var/log # 跳转cd - # 回到上一次的目录(神技,配合两个目录来回切超爽)cd ~ # 回家目录
新人最容易忽略 ls -lah 里的 h——不加这个参数,大文件显示成 8589934592,加了显示成 8.0G,一眼就能看出来。
find vs locate vs which:找东西的三种姿势
# find:实时遍历目录,慢但准find /etc -name "nginx.conf"find . -type f -mtime -1 # 最近 1 天修改过的文件find . -size +100M # 大于 100M 的文件find . -name "*.log" -delete # 找完直接删(危险,先去掉 -delete 看一眼)# locate:基于数据库,秒回但可能不是最新(先 updatedb 更新索引)locate nginx.conf# which:找命令是哪个二进制文件which nginx# /usr/sbin/nginx
新人常见误区是上来就 find / -name xxx,整盘扫描会把 IO 打满,生产机器上等于自杀。正确姿势永远是先限定目录:find /etc -name xxx、find /var/log -name xxx,知道大概在哪个目录再扫。
tree:目录树可视化(要装)
sudo apt install treetree -L 2 /etc/nginx # 只展开 2 层,免得刷屏tree -L 2 --dirsfirst # 目录在前文件在后
tree 默认不装,但强烈建议每台机器装一下,看项目结构比 ls -R 直观 10 倍。
三、看什么(查看文件)
cat / less / tail / head:四种看文件的姿势
cat /etc/hostname # 短文件一次性看完cat -n nginx.conf # 带行号less /var/log/nginx/error.log # 长文件分页看(推荐!比 more 强)# less 里的快捷键:# /pattern 向下搜索# ?pattern 向上搜索# n / N 下一个 / 上一个匹配# G 跳到文件末尾# gg 跳到文件开头# q 退出tail -f /var/log/nginx/access.log # 实时跟随文件追加(**调试线上最常用**)tail -100 access.log # 看最后 100 行tail -f -n 0 access.log # 从当前位置开始 follow,不打印历史head -50 file.log # 看前 50 行
tail -f 是线上排查使用率最高的命令,几乎所有「应用突然报错怎么办」的回答都包含这一条。
grep / awk / sed:文本三剑客(前两个必会)
# grep:找包含某字符串的行grep "ERROR" /var/log/nginx/error.loggrep -i "error" file.log # -i 不区分大小写grep -n "error" file.log # -n 显示行号grep -v "DEBUG" file.log # -v 反向匹配(排除)grep -r "TODO" ./src # 递归搜索目录grep -A 3 "ERROR" file.log # 匹配行 + 后 3 行(上下文超有用)grep -B 3 "ERROR" file.log # 匹配行 + 前 3 行grep -C 3 "ERROR" file.log # 匹配行 + 前后各 3 行# awk:按列处理(默认空白分隔)awk '{print $1}' access.log # 打印第 1 列awk -F: '{print $1}' /etc/passwd # 用 : 当分隔符awk '$9 == 500 {print $7}' access.log # Nginx 日志:找返回 500 的 URLawk '{count[$1]++} END {for(ip in count) print ip,count[ip]}' access.log | sort -rn -k2 # 统计访问最多的 IP# sed:流式替换(小心,-i 会原地改文件)sed 's/old/new/g' file.txt # 输出到屏幕,不改原文件sed -i 's/old/new/g' file.txt # 原地修改,**先备份**sed -i.bak 's/old/new/g' file.txt # 修改并自动备份成 file.txt.bak
awk 一行神技值得专门花半小时练。线上从 100 万行日志里统计 Top 10 访问 IP:
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10
wc:行数 / 字数统计
wc -l file.log # 多少行cat file.log | grep ERROR | wc -l # 多少行 ERRORls /etc | wc -l # /etc 下多少个条目
四、改什么(文件与权限)
touch / mkdir / cp / mv / rm
touch newfile.txt # 创建空文件,或者更新已有文件的时间戳mkdir mydir # 创建目录mkdir -p a/b/c/d # 递归创建多层目录(**-p 必加,不然中间层不存在会报错**)cp src dest # 复制文件cp -r src_dir dest_dir # **复制目录必须加 -r**cp -a src dest # 保留所有属性(权限、所有者、时间戳)—— 备份场景必用mv old new # 重命名 / 移动(**不需要 -r**)mv /tmp/file.log /var/log/ # 跨目录移动rm file # 删文件rm -r dir# 删目录rm -rf dir# 强删,**生产慎用**
两条让人睡不着觉的提醒:
cp -r 复制目录、mv 不需要 -r——cp 不加 -r 复制目录会报错,mv 不需要因为它本质是改 inode 指针不真复制> 会覆盖、>> 才是追加:echo abc > file.log 会清空原内容,echo abc >> file.log 才是追加,这个错栽过的人都懂
rm -rf 的三种翻车姿势
# 翻车 1:变量为空,删根DIR=""rm -rf $DIR/* # → 实际执行 rm -rf /* 💀# 翻车 2:路径手抖加空格rm -rf /usr /local/bin # 本想删 /usr/local/bin,加了空格删了整个 /usr# 翻车 3:通配符配合相对路径cd /tmp/myprojectrm -rf */ # 如果 cd 失败,仍在 /,删 /*
自我保护的三条铁律:
- 生产环境永远先
ls 一遍再 rm:ls $DIR/* 看清楚再 rm -rf $DIR/* - 脚本里强制校验路径不为空:
[ -z "$DIR" ] && { echo "DIR empty, abort"; exit 1; } - 重要数据用
trash-cli 替代 rm:apt install trash-cli,删的东西进回收站,能 trash-restore
chmod / chown:权限与属主
chmod 755 script.sh # rwxr-xr-x(数字法)chmod +x script.sh # 给所有人加可执行chmod u+x,g-w script.sh # 符号法:u/g/o 分别加减chown user:group file # 改属主和属组chown -R nginx:nginx /var/log/nginx # 递归改
权限单独一篇细讲(W2),这里先记住:chown 改属主、chmod 改权限,别搞混顺序。
五、联网(基本网络)
ping / curl / wget:联通性 + HTTP 探测
ping baidu.com # 测连通性(**有些机器禁 ICMP,ping 不通不代表不通**)ping -c 4 baidu.com # 只发 4 个包就停(不加 -c Mac 会一直发)curl -I https://example.com # 只看响应头(最常用)curl -v https://example.com # 详细输出,包括 TLS 握手过程curl -o output.html https://example.com # 下载到文件curl -X POST -H "Content-Type: application/json" \ -d '{"name":"test"}' http://api.local/users # POST JSONwget https://example.com/file.tar.gz # 下载文件,会自动断点续传wget -c https://example.com/big.iso # 显式断点续传
curl -I 配合 -v 是排查 HTTPS 问题的标配,能看到证书链、TLS 版本、握手过程。
ssh / scp / rsync:远程操作
ssh user@host # 登录ssh -p 2222 user@host # 指定端口ssh user@host "ls /var/log"# 远程执行单条命令scp file.txt user@host:/tmp/ # 上传文件scp user@host:/tmp/file.txt . # 下载文件scp -r dir user@host:/tmp/ # 上传目录rsync -avz src/ user@host:/dest/ # 增量同步(推荐替代 scp)# -a 保留属性、-v verbose、-z 传输压缩
为什么生产推荐 rsync 不推荐 scp:rsync 是增量同步,第二次只传变化的文件;scp 每次全量重传,几个 G 的目录传完一动又得重头。
ss:替代 netstat 看连接
ss -lntp # 看 TCP 监听 + 进程(**最常用**)ss -tnp # 看活跃 TCP 连接 + 进程ss -tan state established | wc -l # 数当前 ESTABLISHED 连接ss -tan state time-wait | wc -l # 数 TIME_WAIT
netstat 已经被各发行版边缘化甚至不预装了,新机器统一用 ss。ss 是基于内核 netlink 拿数据,比 netstat 遍历 /proc/net/tcp 快一个数量级。
六、进程(看运行的东西)
ps / top / htop:看进程
ps aux # 看所有进程(BSD 风格)ps -ef # 看所有进程(System V 风格,等价)ps aux | grep nginx # 找 nginx 相关进程top # 实时进程视图,按 P 按 CPU、按 M 按内存排序htop # 升级版 top,**强烈推荐装一下**
htop 比 top 好用太多:彩色、可鼠标、F9 直接 kill、F5 看进程树。新机器一上去先 apt install htop。
kill / pkill / killall
kill 12345 # 默认发 SIGTERM(15),让进程优雅退出kill -9 12345 # 发 SIGKILL,强杀(**最后手段**)kill -HUP 12345 # 发 SIGHUP,很多服务用这个 reload 配置(如 nginx)pkill nginx # 按名字杀pkill -f "python app.py"# 按完整命令行匹配killall nginx # 按精确进程名杀
信号选择的铁律:永远先 kill -15(默认)给应用清理时间,5-10 秒不退再 kill -9。直接 -9 会让应用没机会写日志、提交事务、释放锁,生产故障一半的怪事都是 kill -9 留下的。
nohup / & / setsid:让进程后台跑
# 简单后台(关掉终端进程也会死)./long_task &# 真正脱离终端(推荐)nohup ./long_task > out.log 2>&1 &# 完全脱离会话(最干净)setsid ./long_task > out.log 2>&1 < /dev/null &
nohup 把信号忽略,& 放后台,> out.log 2>&1 把标准输出和标准错误都重定向到文件。少了 2>&1 错误信息会丢,调试时哭都来不及。
七、压缩与归档
# tar 是 Linux 圈的瑞士军刀,记住两条就够了tar -zcvf out.tar.gz dir/ # 打包 + gzip 压缩(c = create)tar -zxvf in.tar.gz # 解包 + 解压缩(x = extract)tar -zxvf in.tar.gz -C /opt/ # 解压到指定目录(-C 必加,不然解到当前目录)tar -tf in.tar.gz # 只看包里有什么,不解出来# zip / unzip(跨平台场景)zip -r out.zip dir/unzip in.zip -d /opt/
参数记忆口诀:c = create、x = extract、v = verbose、f = file(指定文件名,必加)、z = gzip、j = bzip2。
八、帮助系统
man ls# 看完整手册(按 q 退出)ls --help# 看精简帮助(更快)typecd# 看命令是 builtin 还是外部tldr tar # **新人神器**,给一句话 + 5 个常见用法
tldr 是 man 的简版,专门给「我就想知道这命令怎么用」的人:
# 装一下sudo apt install tldrtldr tar# 输出大概是:# Archiving utility.# Create archive from files: tar cf target.tar file1 file2 file3# Create gzipped archive: tar czf target.tar.gz file1 file2 file3# Extract: tar xf source.tar
新人第一周强烈推荐装 tldr,比翻 man 手册效率高 10 倍。
九、5 个能让你少敲很多字的日常 alias
把下面这几条加到 ~/.bashrc 或 ~/.zshrc 里,source ~/.bashrc 生效:
# 1. ll 是 ls -lah 的快捷方式(很多发行版已自带,没有就加)alias ll='ls -lah'# 2. grep 默认开高亮,看着不眼瞎alias grep='grep --color=auto'# 3. history 带时间戳(默认只有序号,看不出什么时候敲的)export HISTTIMEFORMAT="%F %T "# 4. rm 加 -i 确认(自己机器开,服务器别开,脚本会卡死)aliasrm='rm -i'# 仅个人开发机推荐# 5. 服务器上挂着不掉,timeout 调大export TMOUT=0 # 0 = 永不超时
HISTTIMEFORMAT 那条强烈建议所有服务器都开,事故排查时能精确到秒看到当事人敲过什么。
十、命令速查表(每天 90% 用到的就这些)
| | | |
|---|
ls -lah | | -lt | |
cd - | | | |
cat | | less | |
tail -f | | -n 100 | |
grep -rn | | -A/-B/-C | |
find | | -name -type -mtime | |
awk '{print $1}' | | -F: | |
ps aux | grep | | | |
top | | | |
kill -15 | | -9 | |
ss -lntp | | -tnp | |
curl -I | | -X POST -d | |
df -h | | du -sh * | |
tar -zxvf | | -C | |
chmod | | -R | |
剩下没列的命令(vim、systemctl、docker、journalctl 等)都属于「面向场景的命令」,会在后续周分别专题讲。
写在最后
- 按场景背命令,不要按字母背
tail -f + grep + awk 三件套吃掉 80% 的日志排查需求rm -rf 永远先 ls 一遍kill 永远先 -15 再 -9- 新机器进去先装
htop + tldr,加 HISTTIMEFORMAT - 这 30 个背熟之后,再去学
sed 复杂用法、xargs 管道扩展、jq 处理 JSON 等长尾命令