上周帮同事处理一台新装的服务器,服务进程起来了,页面却一直打不开。他抱着一本打印出来的“Linux常用命令大全”翻,翻到三分之一处抬头问我:“文档里怎么没有‘让页面能访问’这条命令?”我问他:“你ss -tulnp看过没有?”他反问“这个命令能干嘛”——那一刻我突然意识到,问题不在命令背得少,而在于看不懂命令和命令之间的“上下文”。今天这篇东西不是再给你列一遍命令清单,而是把搜索量最高、面试最爱问、日常排查最常用的那些Linux命令,放到真实的场景里,讲清楚它们为什么存在、什么时候用、怎么用才稳。
1. 别背命令清单:先理解命令存在的“上下文”
网上随便一搜“linux常用命令”,出来的全是几百条命令的表格,看着很全,但真正遇到故障时,没有一条能直接救命。原因很简单:命令是工具,不是答案。工具只有在你知道“当前问题属于哪一类”时才有意义。
1.1 一次网络故障是如何被解决掉的
回到开头那个同事的问题。服务进程起来了,页面打不开,我带着他走了一遍完整排查链路:
ping 127.0.0.1:先确认本机协议栈是否正常。这条命令看着低级,但它能快速排除“网卡驱动是不是崩了”这种最底层问题。ip addr:看网卡有没有拿到IP,子网掩码和网关对不对。很多“网络不通”的根因就是IP没配上。ping 网关IP:网关通,说明二层链路没问题;网关不通,问题大概率出在交换机端口或网线。ss -tulnp:确认服务进程到底有没有监听端口、监听在哪个地址上。常见坑是服务只监听了127.0.0.1,外部当然访问不到。curl -v http://127.0.0.1:在服务器本机访问一次,验证Web服务本身是否正常。iptables -L -n或firewall-cmd --list-all:最后再检查防火墙规则。
走完这一步,问题立刻暴露:他在配置Nginx时把listen写成了listen 127.0.0.1:80,外部请求全被拒之门外。整个过程我们用了不到五分钟,靠的不是记忆力,而是“网络不通”这个问题对应的排查顺序。
1.2 命令背后是概念模型,不是字母组合
Linux命令的体系其实可以拆成几张大图:文件与目录、用户与权限、进程与信号、网络与端口、存储与挂载、日志与文本处理、包管理。每一个操作都能归到其中一类。你在做chmod时,脑子里想的是“权限模型里的属主/属组/其他人这段该给什么”,而不是“哦我要改权限所以打chmod”。
有了这张地图,命令就不再是零散碎片。比如你理解了“挂载”这个概念,就会明白为什么mount、umount、lsblk、blkid、/etc/fstab这些命令和文件会出现在一起;理解了“信号”之后,kill -15和kill -9的区别你一辈子都不会忘。这也是为什么很多云厂商和面试官,喜欢让候选人现场模拟排查全流程,而不是问“ls -l输出中第三列是什么”这种背答案的题。
2. 文件和目录操作:从“会用”到“用得稳”
文件操作是Linux的绝对基本功,但越是基础的东西,越容易在细节上翻车。很多人每天用ls、cd、cp,却不知道它们还有一票能省时间的参数。
2.1 ls、cd、cp 里被忽略的细节
先说ls。默认的ls输出在你眼里可能只有文件名,但运维场景里最常用的是这几个变体:
ls -lh:人类可读的大小,一眼看出哪个文件占了几个G。ls -lt:按修改时间倒序排列,排最上面的一定是刚变过的文件。排查问题时我几乎只用这条。ls -d */:只看当前目录下的子目录,不会把目录里的内容也列出来。ls -i:显示inode号。inode这个东西在你后面遇到“磁盘明明有空间但创建不了文件”时,就是救命线索。
cd也有两个好用的小技巧:cd -是回到上一次所在的目录,在长路径之间来回切换时比打全路径快得多;cd ~回当前用户家目录,cd ~otheruser直接进别的用户家目录(前提是权限允许)。
cp的坑稍微多一点。最常见的是拷贝目录时漏了-r,报错omitting directory。进阶场景里,cp -a比cp -r更保险,因为-a等价于“递归+保留所有属性”,包含时间戳、权限、软链接,甚至ACL。做备份时如果用cp -r,拷出来的文件时间戳会变成当前时间,后面写增量同步脚本时很容易误判“文件变了”。另一个容易被忽略的是cp -u,它只在源文件比目标文件新时才覆盖,很适合做日常同步。
还有mv。很多人不知道mv跨文件系统时不是“改个名字”,而是先cp再rm。所以你移动一个大文件到另一个分区时,如果突然变得特别慢,不要惊讶,它正在复制而不是移动。这种场景下,用rsync做先传输后删除更稳妥,还能断点续传。
2.2 通配符、引号和重定向:组合命令的基本功
单条命令威力有限,把命令串起来靠的是通配符、引号、重定向和管道。这四样东西是Shell的语法基础,也是新手最容易踩坑的地方。
通配符*、?、[ ]在Shell里做的是“路径匹配”,比如rm *.log删除当前目录下所有.log文件。注意这里只匹配文件名,不匹配隐藏文件(以.开头的),如果你真想删,得写rm .*.log或find配合。
引号的问题更隐蔽。双引号里的$变量和反引号会被执行,单引号里的内容永远是字面量。区别一下这两句:
echo "当前用户: $USER" echo '当前用户: $USER'第一行输出的是用户名,第二行原样打出$USER。写脚本时如果忘了加引号,文件名里的空格会把命令拆成好几段,比如:
# 危险:如果文件叫 "my file.txt",这里会被拆成 rm my file.txt rm my file.txt # 安全: rm "my file.txt"重定向的方向也要记牢:>覆盖写入,>>追加写入,2>&1是把标准错误合并到标准输出。排查问题时我几乎固定用这套:
tail -f /var/log/nginx/error.log >> /tmp/error_记录.log 2>&1 find / -name "*.conf" 2>/dev/null | xargs grep "listen"find的报错信息通常又多又杂,2>/dev/null把权限不足的报错丢掉,只看结果。管道符号|把前一条命令的输出变成后一条的输入,但要注意有些命令(比如rm)不读标准输入,这时候要配合xargs使用。
3. 系统状态与网络排查:从 top 到 ss 的定位链路
“服务器卡了”“网站很慢”“端口起不来”——这些含糊的表述背后,其实对应着一套固定的命令组合。学会看系统状态,比背再多的手册都有用。
3.1 CPU、内存、磁盘:三个常用命令的读法
机器卡了第一反应是敲top,但很多人只会看CPU那一行,然后就不知道该看什么了。我建议配合free -h和df -h一起看,因为“卡”的原因可能是CPU、内存、磁盘任意一个。
free -h里最容易被误解的是buff/cache列。这部分内存是Linux拿来当文件缓存的,应用要内存的时候会被自动释放。所以看到free那一列数字很小不要慌,重点看available,这个值才是“实际可用来分配新内存的空间”。
df -h看磁盘剩余,du -sh *看当前目录下每个子目录占多大。还有一种更隐蔽的情况:df -h显示还有50G,但系统报“No space left on device”,这时候要看inode。用df -i查一下,inode用满了同样写不了新文件。这种情况多半是某个目录下产生了海量小文件,比如没轮转的日志、定时任务的临时文件。
top里三个load average数值值得多说一句。它们分别代表1分钟、5分钟、15分钟的平均负载。如果15分钟很高但1分钟很低,说明问题已经持续了一段时间且在缓解;如果1分钟突然飙高而15分钟很低,说明刚发生了一次突发流量或任务。还要留意zombie僵尸进程的数量,如果一直保持两位数以上,说明某个父进程没有正确回收子进程,该动手排查了。
3.2 网络排查:从 ping 网关到 ss 看端口
网络排查有一个固定的顺序,从底层往上层走,而不是一上来就怀疑应用配置。
先ping网关IP,确认链路通不通;再看ip addr和ip route确认地址和路由;然后用ss -tulnp确认端口监听。下面是标准的排查对照表:
| 症状 | 先查命令 | 查什么 |
|---|---|---|
| 外网IP ping不通 | ping 网关IP | 交换机、网线、本机网卡 |
| 网关通但外网不通 | ip route或cat /etc/resolv.conf | 默认路由、DNS |
| 浏览器打不开页面 | curl -v http://127.0.0.1 | 本机Web服务是否正常 |
| 端口无法访问 | ss -tulnp | 服务是否监听0.0.0.0还是只有127.0.0.1 |
| 端口通但响应慢 | free -h、top、df -h | 资源瓶颈 |
ss -tulnp几乎成了我对“端口”问题的第一反应,它同时告诉你协议、监听地址、端口、进程名和PID。老一点的教程还在让你用netstat,在新版系统里netstat常常没装,而且输出格式不如ss清晰。
curl是排查HTTP问题的利器。curl -v能看到完整的请求响应头和握手过程;curl -I只看响应头;curl -k跳过HTTPS证书校验。如果你怀疑DNS解析有问题,先ping域名看能不能解析成IP,再用nslookup或dig查具体解析结果。
4. 用户、权限与提权:安全边界的日常操作
用户管理和权限控制是Linux里最容易“差不多就行”的部分,可恰恰是安全问题的重灾区。热搜里“linux新建用户”和“linux提权”都排得很靠前,我就把这两块放在一起讲。
4.1 新建用户:useradd 的参数别凭感觉写
很多教程会让你用useradd test,回车,完事。但这样建出来的用户通常没有家目录,也没有正常的Shell,等你su test切过去,看到的提示符都是难看的$,连~都不存在。原因很简单:不同发行版的useradd默认参数不一样。
建议记住这一条最实用的写法:
useradd -m -s /bin/bash -G wheel deploy-m创建家目录,-s指定登录Shell为bash,-G把用户加入附加组。wheel或sudo组一般是用来授予sudo权限的组,具体名称取决于发行版,CentOS系常用wheel,Debian/Ubuntu是sudo。
创建完用户后,别忘了设置密码:
passwd deploy id deployid能看到用户的UID、GID和所属组,排查权限问题时必用。顺便说一句,adduser其实是Debian系提供的一个更友好的交互式命令,会一步步问你要不要设密码、要不要创建家目录。在Ubuntu上顺手,但在CentOS/RHEL上默认没有,用useradd更通用。
4.2 权限模型与 sudo 的最小授权原则
Linux权限模型是“属主-属组-其他人”三段式。chmod 755 file里的数字代表二进制位的叠加:4是读,2是写,1是执行。所以7=4+2+1,5=4+1。我的建议是,普通文件能用644就用644,可执行文件或目录用755,需要修改的配置归到属主可控范围内。
chown用来改属主属组,比如把某个目录交给deploy用户:
chown -R deploy:deploy /data/app-R递归改整个目录树,这是部署项目的标配动作。经常有人只改了文件属主,忘了改属组,结果同属组的协作账号还是没法写文件。
还有一个安全习惯:不要随手chmod 777。在你面前它只是解决了“所有人都能写”的权限问题,在攻击者眼里,它就是“任何账号都能篡改文件”的入场券。能用chown解决归属问题就不要用777兜底。
sudo的授权规则写在/etc/sudoers里,修改时必须用visudo而不是直接拿vim编辑,因为visudo会做语法检查,改坏了还能拦住你,避免sudo全线瘫痪。最小授权原则是:只给“确实需要”的命令放行。例如:
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx这行的意思是,deploy用户不需要输密码就能重启nginx,但仅限这一条命令,他无权用sudo执行其他操作。这比直接给一个deploy ALL=(ALL) ALL要安全得多。
4.3 普通用户提权执行命令的正规姿势
热搜里的“linux提权”,在运维语境下,本质上是“当前用户权限不足,需要用更高权限执行命令”。正规做法就三条路:sudo、su -、登录root。
sudo command是“以root身份执行这条命令,但仍保持当前用户身份”,适合临时执行单个管理命令。su -是彻底切换成root用户,会加载root的环境变量,适合需要连续执行一系列管理操作的时候。sudo -i的效果类似su -,但使用的是当前用户sudo权限映射到root的登录环境。
日常使用中,我自己是这么划分的:单条命令用sudo,成批管理操作用sudo -i,平时绝不直接拿root登录系统。另外,密码输入时的“提权”只是临时生效,sudo默认几分钟内不会再要密码,这是时间窗口保护机制,别因此认为root权限永远不设防。
5. 存储挂载:从手动 mount 到开机自动挂载
存储这块,热搜里“linux挂载nas存储”直接出现过。磁盘和分区管理其实不难,但坑也不少,尤其是/etc/fstab写错导致开机失败的,我碰到过好几次。
5.1 lsblk 与 blkid:先搞清楚盘在哪
插了一块新硬盘后,很多人直接蒙了:“盘在哪里?”先别急着fdisk,用lsblk看一下:
lsblk输出是一棵清晰的树状结构,sda、sdb、nvme0n1这些是物理磁盘,下面的sda1、sda2是分区,mountpoint列显示当前挂载到哪个目录了。如果新盘没有分区,你会看到一大块没有挂载点的裸设备。
blkid会显示分区的UUID和文件系统类型。为什么非得用UUID?因为设备名(比如/dev/sdb1)在重启后可能变化,插拔顺序一变,sdb就可能变成sdc,而UUID是固定的。
blkid /dev/sdb1如果这块盘还没格式化,file -s /dev/sdb1能看到当前文件系统类型,输出data说明还没文件系统。格式化命令是mkfs.ext4 /dev/sdb1,但我要提醒一句:这行命令不可逆,执行前必须确认盘符没写错,否则数据清零的悲剧追不回来。
5.2 fstab 的正确写法和常见坑
手动挂载很简单:
mount /dev/sdb1 /data但重启之后就失效了。要实现开机自动挂载,得写进/etc/fstab。每一行的四个字段分别是:设备标识、挂载点、文件系统类型、挂载选项。
UUID=xxxx-xxxx /data ext4 defaults 0 2写完之后用mount -a验证一次,这条命令会重新读取fstab并尝试挂载所有未挂载的项。如果执行后没有报错,说明配置基本没问题;如果报错,千万别急着重启,否则可能进不了系统。
挂载NAS或网络存储用的NFS,写法也类似:
mount -t nfs 192.168.1.10:/srv/nas /mnt/nasNFS在fstab里的挂载选项建议加上_netdev,意思是“网络就绪之后才挂载”。不加的话,系统启动到挂载这一步时网络可能还没就绪,直接挂载失败,严重的会拖慢开机甚至进入紧急模式。
还有一个经常踩的坑:umount时提示“target is busy”。这不是权限问题,而是有进程正占用着这个目录,最稳妥的定位命令是lsof +D /mnt/nas或fuser -mv /mnt/nas,找到占用进程后处理掉,再卸载。
6. 进程管理:定位、信号和修改进程名的进阶玩法
“linux 修改进程名称”这个热搜词很带感,说明已经不满足于ps和kill了。从基础到进阶,这条线我一次讲透。
6.1 ps、pgrep、kill 的协同套路
ps aux永远是第一选择。它输出两列关键信息:%CPU和%MEM可以快速定位谁在吃资源;STAT列里的Z表示僵尸进程,D表示不可中断的IO等待,这两种状态都非常值得关注。
定位到PID之后,常规操作是kill PID。但这里有个细节:kill默认发送的是TERM信号(数字15),它能请求进程“正常退出”,给进程机会做清理工作。只有kill -9才是强杀。很多人一上来就-9,其实风险很大——进程来不及落盘就可能丢数据。正确顺序是:先kill,等2-3秒看进程还在不在,不行再kill -9。
信号类型用kill -l查看,比较常用的是HUP(1)、TERM(15)、KILL(9)。HUP经常用来触发进程重读配置,比如Nginx的nginx -s reload,内部就是发HUP信号。
大量进程的匹配可以用pgrep,例如pgrep -f "python.*app.py",它会按完整命令行匹配,比按进程名更精确。杀一批时用pkill -f要格外小心,它按模式匹配,很容易误杀,比如pkill -f app可能把myapp、xapp一起干掉了。
6.2 修改进程名称:运维脚本里的实用技巧
为什么有人要改进程名?典型的场景是:监控系统只认进程名,但你又想让同一脚本跑多个实例;或者你想让日志、故障dump里能看到更清晰的标识。
最简单的做法是在启动脚本里用exec -a:
# 以 myworker 这个名字启动 python 脚本 exec -a myworker python3 /opt/scripts/worker.pyexec会把当前Shell进程替换成目标进程,同时用-a指定了argv[0],也就是进程在ps里显示的名字。修改后,ps aux的COMMAND列就能看到myworker而不是python3了。
如果你想改得更彻底,连/proc/PID/comm也一起改,可以用Python的setproctitle库:
import setproctitle setproctitle.setproctitle("data_worker_01")这会同步修改进程名,让top、ps、systemd甚至监控脚本都能用新名字匹配。注意一条:/proc/PID/comm最多只能保存15个字符,超过会被截断。这不是bug,是内核的限制。想要更长的标识,看/proc/PID/cmdline里的argv[0]。
6.3 进程间通信:几个值得知道的操作入口
热搜里还有“linux进程间通信”这个关键词,实际工作中你用命令也能观察到一部分。最基础的通信方式是管道,一条ps aux | grep nginx就是一个匿名管道。更结构化的方式还有共享内存和消息队列,查看它们的命令是ipcs:
ipcs -m # 查共享内存 ipcs -q # 查消息队列 ipcs -s # 查信号量当系统里出现奇怪的IPC残留对象时,可以用ipcrm清理,防止占满系统限制。信号本质上也是进程间通信,kill -15 PID就是在“告诉进程‘该停机了’”。理解了这一层,很多命令就不再是孤立的开关了。
7. 日志与文本处理:grep、awk、sed 三板斧的应用范式
系统出了问题,第一手证据都在日志里。能不能快速、精准地从日志文件中抽出关键信息,拼的就是文本处理功底。
7.1 日志排查的标准动作:tail、grep、journalctl
最常用的肯定是tail -f,滚动模式看新日志。排查时我一般先把日志文件整个翻一遍,用grep -i error找到所有错误行,再按时间窗口缩小范围。grep的几个参数要熟练:-E支持扩展正则,-v反选,-c计数,-n显示行号。
如果用的是systemd体系,journalctl是主力:
journalctl -u nginx.service -f # 只看nginx服务日志,滚动输出 journalctl --since "10 minutes ago" # 按时间过滤 journalctl -p err # 只看错误级别及以上很多系统服务启动失败时,屏幕上只给一句“Active: failed”,但真正的错误细节藏在journalctl -xe里。-x补充解释条目,-e直接跳到日志末尾,这条命令是我听完“服务起不来”之后的第一反应。
7.2 awk 与 sed:从日志里提取你要的信息
awk最常见的用法是按列抽取字段。访问日志里每行以空格分隔,第一个字段是客户端IP,这就构成了统计基础:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10这条管道命令分四步:提取IP -> 排序 -> 去重并计数 -> 按次数倒序。得到的就是访问量最高的前10个IP。如果你要按其他分隔符切分,用-F指定,比如awk -F':' '{print $2}'。
sed的核心能力是替换和按范围取值。比如把所有旧域名批量替换成新域名:
sed -i 's/old.example.com/new.example.com/g' /etc/nginx/conf.d/*.conf-i直接改写原文件,实际操作前建议先去掉-i跑一遍看输出是否符合预期,确认无误再真正落盘。要查看日志中某个时间段的内容,可以用sed -n '/2025-01-01 10:00/,/2025-01-01 10:30/p' app.log,按起止行模式提取区间,比纯grep更灵活。
8. 包管理与镜像源:装软件遇到依赖问题怎么破
软件安装是绕不开的日常操作。热搜里“linux系统安装python”“linux下载gcc编译器”“debian换清华源”这些词,本质都是同一个问题:怎么把软件正确、稳定地装到系统里。
8.1 apt/yum/dnf 的日常用法
Debian/Ubuntu系用的apt,CentOS/RHEL系用的yum或dnf,命令结构高度相似:
apt update && apt upgrade -y apt install nginx apt search python3yum install -y httpd yum search gcc dnf install -y gcc一个关键区别:apt update只是更新软件源索引,不升级软件;upgrade才是真正升级。很多新手以为update完就算更新了,其实索引刷完之后还有一步。生产服务器不建议一上来就upgrade,升级系统库可能引发连锁重启,最好在业务窗口期操作。
yum和dnf的区别可以这样理解:dnf是yum的下一代实现,性能更好、依赖解析更健壮。在RHEL 8/9和Fedora上你已经找不到yum了,取而代之的是dnf(有时保留了yum兼容命令名)。
8.2 换源与依赖问题处理
国内环境访问官方源经常慢到怀疑人生,换一个更快、更稳定的镜像源是常规操作。以Debian为例,编辑/etc/apt/sources.list,换成清华源:
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free换完之后执行apt update重新加载索引。CentOS系的源配置在/etc/yum.repos.d/目录里,修改后同样用yum clean all && yum makecache重建缓存。注意一点:不要混用不同发行版的源,否则依赖版本可能直接冲突到系统崩溃。
编译安装GCC这类编译器时,很多新手卡在./configure那一步,其实报错大多是缺少依赖头文件。先用包管理器装好build-essential(Debian系)或Development Tools组包(RHEL系)再编译,能省一半的折腾。编译完成后,可以用ldd /usr/local/bin/gcc检查动态库依赖是否能找到。
依赖问题是包管理中最烦的,常见报错是libxxx.so.x: cannot open shared object file。这个报错的含义是程序运行时没找到某个共享库。用ldconfig -p | grep libxxx看看系统库缓存里有没有;如果库存在只是路径没找对,临时设置LD_LIBRARY_PATH=/usr/local/lib,永久方案是编辑/etc/ld.so.conf.d/下新建一个.conf文件,然后执行ldconfig刷新缓存。
9. 面试高频自检:这些点你都能说清楚吗
“linux面试题测试”和“运维linux常用命令大全”能上热搜,说明大家确实在为面试准备。最后我按面试官视角,把上面这些内容浓缩成一张自检清单。
9.1 高频面试题快答
| 面试问题 | 快速回答 | 给出要点 |
|---|---|---|
| 查看某个端口被谁占用 | ss -tulnp | grep :80 | 监听地址、PID、进程名 |
| 内存不够怎么排查 | free -h看available | buff/cache可回收 |
| 查找一个大文件 | find / -type f -size +1G | 配合du -sh进一步定位 |
| 给文件/目录授权 | chmod 755chown user:group | 不要滥用777 |
| 创建新用户 | useradd -m -s /bin/bash user | 家目录、Shell、附加组 |
| 查看系统负载 | top、uptime | load1/5/15、僵尸进程 |
| 杀不掉进程怎么办 | 先TERM再KILL | kill -9是最后手段 |
| 服务启动失败看什么 | journalctl -xe | 看详细错误和上下文 |
| 软链接和硬链接区别 | ln -s和ln | 软链是路径引用,硬链是inode引用 |
| 磁盘满但du没看到大文件 | df -i查inode | 海量小文件同样能撑爆磁盘 |
这些问题的共同点是:考察的不是命令本身,而是你对概念的理解。比如“软链接和硬链接”,面试官想听的是“软链指向路径,目标没了就失效;硬链指向inode,多个名字共享同一份数据,硬链不能跨文件系统也不能指向目录”。
9.2 我给新人和面试者的建议
如果一个候选人能把“网络故障排查顺序”完整说下来,从ping 127.0.0.1到网关再到ss再到curl,哪怕个别参数记不全,我都觉得这个人的底子是扎实的。因为他脑子里有排查链路,不是背串场的演员。
给新人的实操建议是:别去背“第3章第5条命令能做什么”,而是给自己攒一套“故障案例笔记”。每解决一个问题,就记录三行——现象、根因、用了哪几条命令。积累到十来个案例之后,你会发现那些命令想忘都忘不掉。
我自己刚入行时,也干过把网上的命令大全复制进文档收藏的蠢事,收藏了等于学会了,第二天全忘光。后来换了方法,每遇到一个问题就只记“那条命令为什么能解决这个问题”,三个月之后,很多命令自己就会从手边冒出来。Linux常用命令从来不是填空题,而是一张地图——你只需要知道哪个方向对应哪个工具,真正要用的时候,命令自己就跳出来了。