Linux 命令速查
命令列表
点行首图标复制文件与目录(9)
-
ls -alh /var/log
列出目录内容,含隐藏文件、大小用人类可读单位
`-a` 带隐藏文件(`.` 开头)、`-l` 长格式、`-h` 人类可读、`-t` 按时间排;`-ld` 是只看目录这一项而不展开它
-
cd /var/log
切换到指定目录
路径里有空格要加引号;`cd -` 依赖 shell 的目录栈,脚本里不一定可用
-
pwd
打印当前所在目录的绝对路径
配合软链接时用 `pwd -P` 拿真实路径而不是链接路径
-
mkdir -p /var/log
建目录,父目录不存在时一并创建
`-p` 让「父目录不存在」不报错、已存在也不报错 —— 脚本里几乎总是要加
-
touch app.log
建一个空文件;文件已存在时只把修改时间更新到现在
-
cp -r /srv/app /var/log
递归复制目录(含其中的所有内容)
拷目录**必须**加 `-r`(递归),否则报 `omitting directory`;想连权限与时间戳一起保留就加 `-a`,备份场景用 `-a` 更稳
-
mv /srv/app /var/log
移动文件 / 目录,目标写新名字就是重命名
同一分区内只是改指针、瞬间完成;跨分区是复制再删,大目录会慢一截
-
rm -rf /var/log
递归强制删除目录,不逐项提示
**不可恢复、不进回收站**。`-r` 递归、`-f` 不确认;路径里多打一个空格就是事故,先 `ls -ld` 确认再删。`:(){ :|:& };:` 那种恶意字符串别往 shell 里粘
危险 -
ln -s /srv/app /var/log
建软链接(类似 Windows 快捷方式)
**源路径写绝对路径**,否则从别的目录访问会断链;`-s` 是软链接,不加是硬链接(不能跨分区、不能指向目录)
查找与搜索(7)
-
find /var/log -name "*.log"
在指定目录下递归按文件名查找
`-name` 区分大小写(`-iname` 忽略大小写);模式要加引号,否则 shell 会先替你展开通配符、结果完全不同
-
find /var/log -type f -size +100M
找出大于 100MB 的文件(磁盘满了先跑这条)
`+100M` 是「大于」,`-100M` 是「小于」;`-type f` 只看普通文件,不然目录也会被算进来
-
find /var/log -type f -mtime + 7 -delete
删除指定天数以前修改过的文件(清理老日志 / 老备份)
**先把 `-delete` 去掉跑一遍**,确认列出的正是要删的那批再加回去;`-delete` 必须放在整个表达式最后
危险 -
locate error
从预建索引里秒查路径(比 find 快得多)
索引由 `updatedb` 定期重建,刚建的文件可能查不到;没装就 `sudo apt install mlocate`(或 `plocate`)
-
which error
查一个命令的可执行文件在哪
找不到多半是没进 `PATH`(或根本没装);已定义的 shell 别名 / 函数 `which` 看不出来,用 `type -a` 更准
-
grep -rn " error " /var/log
在目录下递归搜索文本内容,打出文件名与行号
`-r` 递归、`-n` 带行号、`-i` 忽略大小写、`-l` 只出文件名。只想确认「哪些文件提到了」用 `-l`,比 `-n` 快很多
-
grep -rl " error " /var/log | xargs wc -l
把上一条命令输出的每一行当参数接着处理
文件名带空格时用 `xargs -0` 配 `find -print0`;不加 `-0` 保护就 `xargs rm`,遇到带空格的名字会删错对象
查看与编辑(7)
-
cat app.log
把文件内容整个打印出来
文件很大时别用 `cat`(会刷屏到崩溃),用 `less`;`cat` 也常用来拼文件,如 `cat a.log b.log > all.log`
-
less app.log
分页查看大文件:`/` 搜词、`g` / `G` 跳首尾、`q` 退出
`less` 按需读取、不会把整个文件读进内存,几百 MB 的日志用它才不卡;`less +F` 相当于 `tail -f`
-
tail -n 100 app.log
看文件末尾 100 行
`-f` 会一直挂着看新增内容、`Ctrl+C` 退出;日志被轮转(改名后新建)时要用 `-F`,`-f` 会跟丢
-
wc -l app.log
统计行数
`wc -l` 数是**换行符**个数,最后一行没有换行符时结果会少 1,这是最常见的「行数对不上」原因
-
sed -n '10,20p' app.log
只打印第 10 到 20 行(按行号截取,不必先知道文件多大)
`-n` 关掉默认的整行输出,`p` 才是「打印这一行」;不写 `-n` 会把全文打一遍再重复这两行
-
diff -u app.log /var/log
逐行比较两个文件的差异
`-u` 输出统一格式(带上下文、跟 `git diff` 同一套);只想知道「一不一样」用 `-q`,它只回一行结论
-
vim app.log
用 vim 打开文件编辑
vim 里按 `i` 进入插入、`Esc` 退回、`:wq` 保存退出、`:q!` 不保存强退(卡住了先狂按 `Esc` 再输 `:q!`);nano 是 `Ctrl+O` 保存、`Ctrl+X` 退出
文本处理(8)
-
sort app.log
按字典序排每一行
默认按字符串排,所以 `10` 会排在 `9` 前面;按数值排要加 `-n`,倒序加 `-r`
-
sort app.log | uniq -c | sort -rn
统计每行出现次数并按次数倒序(「谁最多」的标准套路)
`uniq` 只合并**相邻**的重复行,所以前面必须先 `sort`;`-c` 计数、`-rn` 按数字倒序,最上面那条就是出现最多的
-
cut -d "," -f 1 app.log
按分隔符取第几列(这里取逗号分隔的第一列)
`-d` 指定分隔符、`-f` 指定第几个字段;`cut` 只认**单字符**分隔符,多字符或要条件判断就交给 `awk`
-
tr 'A-Z' 'a-z' < app.log
按字符做替换或删除(这里把大写字母都变小写)
`tr` 只按字符一一对应地换、不认单词;处理 Windows 换行(`\r\n`)时 `tr -d "\r"` 是最常见的用法
-
sed -i 's/ error /replace/g' app.log
把文件里的匹配文本批量替换(**直接改原文件**)
`-i` 是**原地修改,改错了没有撤销**。先跑不带 `-i` 的版本看输出确认,或先 `cp` 一份备份;macOS 的 `sed -i` 要写成 `-i ""`
谨慎 -
awk '{print $1}' app.log
按空白切分后取第几列(这里取第一列)
`awk` 默认按连续空白切分,`$1` 是第一列、`$0` 是整行;`-F` 换分隔符。要按条件筛行写 `awk '$2 > 100'`
-
jq '.items[] | .name' app.log
从 JSON 文件里格式化输出并提取字段
`jq` 不是所有系统自带,装一下:`apt install jq` / `brew install jq`;`.items[]` 遍历数组、`|` 把上一步结果接着处理
-
paste -d "," app.log /var/log
把两个文件按行并排合并成一列
`-d` 指定连接符。它**不是**按内容对齐,只是第 n 行接第 n 行;两边行数不等时短的那边留空
权限与属主(6)
-
chmod +x app.log
给文件加上可执行权限(脚本「Permission denied」时跑这条)
`+x` 是「所有人都可执行」;要精确控制用八进制,如 `chmod 755`。`-R` 递归时对目录也会加执行位,通常正是想要的
-
chmod 644 app.log
用八进制设置权限(644 = 属主读写、其他人只读)
三个数字依次是**属主 / 属组 / 其他人**:4 读、2 写、1 执行,相加即得。文件 644、目录与脚本 755 是最常见的两档
-
chown -R deploy : deploy /var/log
把目录及内容的属主与属组一起改掉
需要 root(前面加 `sudo`);`-R` 递归、冒号后面是属组。目录权限不对时**先确认属主再改权限**,顺序反了还得再改一次
-
sudo -u deploy whoami
以指定用户的身份执行一条命令
`sudo -u` 只借用户身份、环境变量基本不动;要连环境一起换用 `sudo -iu`(`-i` 相当于登录一次)
-
id deploy
看用户的 uid / gid 与所属的全部组
不传用户名就是看当前用户;用户改过组之后要重新登录(或 `newgrp`)才生效
-
umask
看新建文件 / 目录的默认权限掩码
输出如 `0022`:新建目录得到 `777 - 022 = 755`、文件得到 `666 - 022 = 644`。它是「扣掉哪些位」而不是「给哪些位」
进程与作业(8)
-
ps aux
列出所有进程(用户、PID、CPU / 内存占用、启动命令)
第二列是 PID(后面 `kill` / `top -p` 都要它);`STAT` 里的 `Z` 是僵尸进程、`D` 一般是卡在磁盘 IO
-
ps aux | grep " error "
按关键词过滤进程,找 PID 最常用的一条
`grep` 自己也会出现在结果里(就是那条 `grep 关键词`),真进程通常看上一行;想更准用 `pgrep -af 关键词`,它不会把自己列进来
-
top -p 12345
实时盯着指定进程的资源占用
`top` 里按 `M` 按内存排序、`P` 按 CPU 排序、`q` 退出;`htop` 需另外安装,能直接鼠标点、按树形看父子进程
-
kill 12345
给进程发 SIGTERM,请它自己收尾退出(优雅停止)
先 `kill` 给它机会保存与关闭连接;`kill -9` 立刻强杀、来不及清理,可能留下锁文件或半截数据,留作最后手段
-
pkill -f " error "
按命令行的关键词批量结束进程
`-f` 匹配整条命令行(不加只匹配进程名)。**先用 `pgrep -af` 确认命中范围**再动手 —— 匹配太宽会把不该杀的(甚至当前 ssh 会话)一起杀掉
谨慎 -
jobs -l
列出当前 shell 的后台作业与它们的 PID
`%1` 是**作业号**(`jobs` 输出里方括号中那个),跟 PID 不是一回事;`Ctrl+Z` 会把当前前台进程挂起成作业
-
nohup ./run.sh > out.log 2>&1 &
让命令在关掉终端后继续跑,输出重定向到日志
`nohup` 挡 SIGHUP、末尾 `&` 放进后台。**不重定向的话默认写 `nohup.out`**;真要长期守护服务,用 `systemd` 而不是 nohup
-
lsof -i : 8080
查端口被哪个进程占用(「Address already in use」时跑它)
「端口起不来 / 启动即退出」先跑这条;`ss -tulnp` 也能看监听,但 `lsof` 连打开的文件、连接、目录都能查(没装就 `apt install lsof`)
系统与资源(7)
-
df -h
看各挂载点的磁盘使用率与剩余空间
`-h` 用 K / M / G 人类可读。`Use%` 到 100% 时写文件会直接失败,先看这条,再用 `du` 找出是哪个目录吃掉的
-
du -sh /var/log
统计目录的总占用(只给一行汇总)
`-s` 只出汇总、`-h` 人类可读;不带 `-s` 会把每个子目录都列一遍,大目录能刷屏几千行
-
free -h
看内存与 swap 的使用情况
看 `available` 那一列才是「还能分给新进程的」;`buff/cache` 占着内存不代表不够用,它会被回收
-
uname -a
看内核版本与系统架构
`uname` 给的是**内核**信息;要判断是 Ubuntu 还是 CentOS、什么版本号,得看 `/etc/os-release`
-
uptime
看开机时长与 1 / 5 / 15 分钟平均负载
负载要**和 CPU 核数比着看**:8 核跑在 8 左右算满载,跑到 16 就是明显排队了。`nproc` 看核数
-
date
看当前系统时间与时区
服务器时间不对(容器里尤其常见)会连带影响证书校验、日志对齐与定时任务,排查异常先 `date` 一下
-
systemctl status nginx
看服务状态、最近日志与开机自启设置
`active (running)` 才算正常;改了 unit 文件要 `systemctl daemon-reload` 再 restart。老系统(无 systemd)用 `service 名字 status`
网络与传输(8)
-
curl -i 192.168.1.10
发一个请求并打印响应头与正文
`-i` 连响应头一起打印、`-I` 只发 HEAD;连不上或怀疑证书时加 `-v`,TLS 握手与请求头都能看到
-
wget 192.168.1.10
下载文件到当前目录
大文件用 `-c` 续传(断了接着下);`wget -O 文件名 地址` 可指定保存名,`curl -O` 是另一套等价写法
-
ping 192.168.1.10
测网络连通性与往返延迟
默认会一直 ping 下去,`Ctrl+C` 停;要固定次数用 `-c`。ping 不通也可能是对方禁了 ICMP,不代表服务不可用
-
ss -tulnp
列出正在监听的 TCP / UDP 端口及对应进程
参数:`t`/`u` 是 TCP / UDP、`l` 只看监听、`n` 不解析域名、`p` 显示进程。老系统把 `ss` 换成 `netstat`(参数一样)
-
ip addr
看本机所有网卡与它们的 IP 地址
新系统用 `ip`(`ifconfig` 属于已废弃的 net-tools,不少发行版默认不装);`ip -br addr` 输出更紧凑
-
dig 192.168.1.10
查域名解析出的 IP 与应答详情
`+short` 只出答案、脚本里好用。域名打不开先确认**解析出来的 IP 对不对**,再排查网络与端口
-
ssh deploy @ 192.168.1.10
登录远程主机
首次连接会问是否信任主机指纹,输 `yes` 才写入 `known_hosts`;换过机器后提示指纹变了,要先删掉旧记录(`ssh-keygen -R 主机`)
-
scp /srv/app deploy @ 192.168.1.10 : /var/log
把本地文件 / 目录拷到远程主机
拷**目录**要加 `-r`。大目录或网络不稳时优先 `rsync`:断点续传、只传变化的部分,`scp` 每次都从头传
压缩与归档(6)
-
tar czf backup.tar.gz /srv/app
把目录打包成 tar.gz
`c` 创建、`z` gzip、`f` 指定文件名(`f` 要放最后紧跟包名)。**先 `cd` 到父目录再打包**,否则包里会带上整条路径
-
tar xzf backup.tar.gz
解压 tar.gz 到当前目录
`x` 解开、`z` gzip、`-C` 指定目标目录(目录要先存在)。来源不明的包先 `tar tzf` 看一眼清单再解
-
zip -r backup.tar.gz /srv/app
压缩成 zip(要发给 Windows 用户时用)
`-r` 递归加目录必须写,不然只会加个空目录;`unzip -l 包名` 可先看清单。zip / unzip 不是所有系统自带
-
gzip -k app.log
把单个文件压缩成 `.gz` 并保留原文件
`-k` 是保留原文件(不加它原文件会被删掉);gzip 只压单个文件、**不带归档**,压目录要先用 `tar`
-
tar --zstd -cf backup.tar.gz /srv/app
用 zstd 压缩(压缩率相近时比 gzip 快不少)
需要较新的 tar(GNU tar 1.31+)与 `zstd` 命令;大目录备份、临时归档优先用它,解压也要加 `--zstd`
-
find /var/log -name "*.log" -print0 | xargs -0 tar czf backup.tar.gz
把搜到的一批文件一起打包压缩
`-print0` + `xargs -0` 是为了兼容文件名里的空格;动手前先把 `| xargs …` 那半段去掉,确认文件列表对不对
命令里加绿底的是你填的值,纯绿字是示例值;本页不执行任何命令,复制到自己的终端里运行。