☰
Linux常见命令与面试题实战:从排查到运维场景精讲
2026/9/29 22:32:48 网站建设 项目流程

1. Linux命令为什么成了面试桌上绕不开的一关

Linux常见命令、Linux面试题这两个词组,几乎是每一个运维、后端、嵌入式乃至测试岗位面试里的固定嘉宾。原因很现实:面试官没办法在四十分钟里看你写完一个完整项目,但他可以让你敲两行命令,立刻判断出你到底有没有真正在服务器上摸爬滚打过。命令这个东西最诚实,背没背过、有没有实际用过,一问细节就露馅。我见过太多简历上写着"熟悉Linux"的候选人,被一句"你怎么找出哪个进程占着8080端口"问得卡在那里。

这篇文章想解决的就是这个问题。我不打算给你一份干巴巴的"命令大全",那种东西网上一搜几百份,背完该不会还是不会。我想做的是把Linux常见命令按面试和实战的真实使用场景重新组织一遍:每一条命令为什么这么设计、参数怎么算出来的、面试官追问的下一句通常是什么、线上真出问题时你该按什么顺序敲。适合刚入行的运维和测试同学,也适合写了几年Java、SpringBoot但对Linux还停留在cd、ls水平的后端同学。前端同学如果平时只碰npm和docker,看完也能补齐服务器这一环。

下面内容都是我在实际带的实习生和面试复盘里反复讲的东西,含参数推算过程和踩坑记录,你可以直接拿去对照练习。

2. 文件与目录:最基础的操作往往藏着最深的坑

2.1 ls、cd、pwd 里被忽略的信息量

很多人觉得ls太简单了,恰恰是这里最能暴露水平。ls -l输出的九位权限串、硬链接计数、属主属组、大小、时间戳,每一项都能被追问。比如第二列那个数字,对普通文件来说是硬链接数,对目录来说是子目录数量加2,因为目录本身有一个.和父目录里指向它的..。这个细节我在面试里问过不下二十个人,能答利索的不到三成。

ls -lh把字节换成人类可读单位,ls -lt按修改时间排序,ls -ltr反过来让最新的排在最下面——这个组合是我排查日志目录时用得最多的,因为新生成的日志总在终端最下方,眼睛不用来回扫。ls -la看隐藏文件,ls -ld /path只看目录本身而不是它里面的内容,这条在查目录权限时特别关键,很多人ls -l /data看到的是文件权限,却误以为看到了目录权限。

cd -回到上一个目录,cd ~回家目录,cd不带参数也是回家目录。pwd -P显示真实物理路径,当你走软链接进来的时候,pwd给的是逻辑路径,pwd -P才是实际位置。这个区别在做脚本时很重要,脚本里用相对路径前最好先cd "$(dirname "$0")"再pwd -P定位,否则被软链接一绕,路径全错。

2.2 创建、复制、移动、删除的正确姿势

mkdir -p a/b/c递归建目录,-p的另一个作用是目录已存在时不报错,脚本里几乎必加。cp -r复制目录,cp -a归档复制,保留权限、属主、时间戳和软链接本身,做备份时用-a而不是-r,区别大了去了。mv在同分区内是改指针,瞬间完成,跨分区才会真的拷贝再删除,所以mv大目录到另一个挂载点时慢是正常的,不是卡住了。

rm是重灾区。rm -rf删目录,rm -i逐个确认,rm -f强制不提示。我在生产上给所有机器加了别名alias rm='rm -i',并且养成了一个习惯:删之前先把rm替换成echo跑一遍,看展开的路径对不对。比如rm -rf $DIR/,如果$DIR是空的,这条命令就变成rm -rf /,后果不用我说。所以脚本里永远写成rm -rf "${DIR:?}/",${DIR:?}的意思是变量为空就报错退出,这一招救过我好几次。

还有个小坑:rm -rf /tmp/*不会删掉隐藏文件,要用rm -rf /tmp/{*,.*}或者干脆find /tmp -mindepth 1 -delete。通配符不匹配隐藏文件这件事,是新手以为"删干净了"结果磁盘没释放的常见原因。

2.3 权限、属主与 umask:把数字算明白

chmod数字法里,r=4、w=2、x=1,三位分别对应属主、属组、其他人。chmod 755 file就是属主7(4+2+1)、属组5(4+1)、其他人5(4+1)。chmod 644是文件的标准权限,chmod 755是目录和可执行文件的标准权限。为什么目录需要x位?因为x对目录意味着"可以进入/穿越",只有r没有x,你能列出目录里的名字却打不开任何文件,这个现象很多人遇到过却不知道为什么。

umask决定新建文件的默认权限。文件基准是666,目录基准是777,实际权限等于基准减去umask。系统默认umask是022,所以新文件是644,新目录是755。如果umask设成027,新文件变成640,新目录变成750。我在做合规要求比较高的环境时会设027,避免同组其他人读走敏感文件。

chown user:group file改属主属组,chown -R递归。复制文件后权限属主不对,多半是没用cp -a或者没用rsync -a。chattr +i file可以给文件加不可修改属性,连root都删不掉,得先chattr -i,这是防误删的最后一道锁,我给关键配置文件加过。

注意:用chmod -R 777解决权限问题,是典型的"用大锤拧螺丝"。它会带来安全风险,而且往往掩盖了真正的属主配置错误。线上环境我从不允许这么干。

3. 文本处理三剑客:grep、sed、awk 的实战解法

3.1 grep:从海量日志里捞出那一行

grep是最常用的文本搜索工具,面试里几乎必问。grep -r "error" /var/log/递归搜目录,grep -n显示行号,grep -i忽略大小写,grep -v反向排除,grep -c只输出匹配行数,grep -l只列出文件名。这几个参数组合起来能干很多活,比如grep -rn --include="*.log" "Timeout" /data/只在log文件里找超时。

真正容易被追问的是grep -w、grep -o和grep -E。-w匹配整词,避免搜"cat"时把"category"也捞出来。-o只输出匹配的那部分而不是整行,提取IP、时间戳时特别好用。-E支持扩展正则,等价于egrep,写grep -E "ERROR|WARN"比写两个grep然后管道合并优雅得多。

举个我常用的例子,从nginx访问日志里找出访问量最高的IP:

awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -20

这条命令的拆解很重要:awk取第一列(客户端IP),sort排序让相同IP相邻,uniq -c统计连续重复出现次数,sort -rn按数字倒序,head -20取前二十。面试官顺着这条命令能问出uniq为什么必须配合sort(因为uniq只处理相邻重复行)、sort -n和sort的区别(是否按数值比较,"10"按字典序会排在"9"前面)。这一个案例能串起五个命令,是我验证候选人熟练度的万能题。

3.2 sed:替换、删除、插入的固定套路

sed默认把结果打到标准输出,不改原文件,加-i才原地修改。这个设计很多人第一次用会懵,以为命令没生效。sed -i.bak会先把原文件备份成file.bak再改,比裸-i安全,我在改配置文件时基本都带.bak。

最经典的替换:sed -i 's/old/new/g' file.txt,g是全局,不加只替换每行第一个。要替换第几处出现,用sed 's/old/new/2'。&代表匹配到的整个内容,sed 's/[0-9]*/【&】/'能给数字加括号。分隔符不一定是斜杠,路径里全是斜杠时换成sed 's#/old/path#/new/path#',可读性立刻上来。

删除和打印:sed '3d'删第三行,sed '/^#/d'删所有注释行,sed -n '10,20p'只打印10到20行(-n关掉默认输出,p显式打印,两者缺一不可,只写-n什么都不输出,只写p会打印两遍)。

批量改配置是sed的主场。比如把配置文件里的listen 80改成listen 8080,同时把所有#注释掉的server_name行取消注释:

sed -i 's/^listen 80/listen 8080/' nginx.conf sed -i '/#server_name/ s/^#//' nginx.conf

第二条的逻辑是:先用/pattern/定位到包含#server_name的行,再对这些行做替换,把行首的#删掉。这种"先定位再操作"的写法比写一条复杂正则更清晰,也更不容易出错。

3.3 awk:按列处理,才是它的灵魂

awk的定位是"按列操作的文本处理器",默认用空格或制表符分列,-F指定分隔符。awk '{print $1, $3}'打印第一和第三列,$0是整行,NF是当前行列数,NR是当前行号,$NF是最后一列——这几个内置变量必须记住。

awk -F: '{print $1, $3}' /etc/passwd # 看用户名和UID awk '$3 > 1000 {print $1}' /etc/passwd # 筛出UID大于1000的普通用户 awk 'NR==3 {print}' file # 打印第三行 awk '{sum+=$1} END {print sum}' nums.txt # 求和 awk '{sum+=$1} END {print sum/NR}' nums.txt # 求平均

条件、求和、计数、格式化输出,awk都能干。面试里常被问的"统计文本某列的和""找出某个字段最大的行",用awk几秒搞定。我排查某个接口耗时分布时,就用awk '{print $NF}'取出日志末尾的耗时字段,再接sort -n | tail看最慢的请求。

三剑客组合起来才是真正威力。找出GC日志里Full GC出现的时间点并统计次数:

grep "Full GC" gc.log | awk '{print $1, $2}' | sort | uniq -c

这里grep过滤、awk取列、sort排序、uniq -c计数,各司其职。你只要能把这个思路讲清楚,面试官就知道你不是背参数,而是真的会用。

4. 进程、端口与性能排查:线上问题的主战场

4.1 进程查看与信号:ps、top、kill

ps aux和ps -ef是两套风格的写法,输出字段略有不同,但本质一样。ps aux | grep java能找到Java进程,但会带出一条grep自己的进程,更干净的做法是pgrep -af java或者ps -ef | grep java | grep -v grep。ps -ef --forest能看进程树,判断父子关系,排查是谁拉起某个僵尸进程时很有用。

top里几个关键指标:load average三个数字是1分钟、5分钟、15分钟的平均负载,如果它长期高于CPU核心数,说明系统排队的进程太多。这不是简单的"CPU不够用",也可能是IO等待导致进程处于D状态。看%wa这一列,如果它很高,说明磁盘IO是瓶颈,加CPU没用。top里按P按CPU排序、按M按内存排序、按1展开每个核心、按H显示线程,这几个快捷键我几乎每次排查都会用到。

kill发送信号,kill -15(SIGTERM)是优雅退出,进程有机会清理资源,kill -9(SIGKILL)是强制杀掉,进程没有任何反抗余地。面试高频追问:"为什么优先用-15而不是-9?"因为-9会让进程来不及释放锁、写完文件、关闭连接,可能留下脏数据和僵尸子进程。-9只应该在进程彻底卡死、-15无效时用。这个问题答得好不好,直接区分出有没有生产经验。

4.2 端口与网络:谁占了我的8080

"端口被占用怎么排查"是Linux面试题里的常青树。标准答案是:

netstat -tunlp | grep 8080 ss -tunlp | grep 8080 # 现代系统推荐,更快 lsof -i:8080 # 直接定位进程

netstat -tunlp的参数拆解:-t是TCP,-u是UDP,-n是直接显示IP和端口号而不做域名解析(快很多),-l是只看监听状态,-p是显示占用端口的进程。少了-n会卡半天,因为它在反查DNS,这是新手最容易忽略的性能点。

ss是新版系统里netstat的替代品,同样参数含义基本一致,速度更快,现在很多精简镜像里根本没装netstat,改用ss。lsof -i:8080直接列出打开这个端口的进程和PID,最直观。如果连接数特别多,可以用ss -s看汇总,ss -tn state established | wc -l统计已建立连接数,判断是否连接耗尽。

curl -v看完整请求过程,telnet host port或nc -zv host port测端口通不通,traceroute看路由跳数(内网排查网络分段有用)。这些是网络问题的基本工具组合。

4.3 磁盘与资源:df 和 du 为什么对不上

df -h看各挂载点的使用率,du -sh *看当前目录下每个子项大小。面试里有个经典问题:"为什么df显示磁盘满了,但du加起来却小很多?"答案通常是:有进程删除了大文件但文件句柄没释放,空间不回收。用lsof | grep deleted能找出来,重启对应进程或kill掉它,空间立刻释放。我遇到过Tomcat日志被rm了但进程还捧着句柄,磁盘一直报警,就是这个原因。

du -sh *看不到当前目录总大小,要用du -sh .。du -ah --max-depth=1只看一层,避免递归太深卡住。找出大目录时我一般按这个顺序:df -h定位是哪个挂载点满,cd进去,du -sh * | sort -rh | head -10一层层剥到元凶。

内存方面free -m看总量、已用、缓存、可用,重点看available而不是free,因为buff/cache是可回收的,Linux的内存哲学是"空闲的内存是浪费的内存"。vmstat 1看上下文切换cs和中断in,iostat -x 1看磁盘%util(接近100%说明磁盘满了)和await(平均等待时间)。这几个命令加上top,构成一套完整的性能排查工具箱。

5. 压缩打包与中文乱码:那个让人抓狂的解压问题

5.1 tar、gzip、zip 的常用组合

tar本身只打包不压缩,配合gzip或bzip2才压。tar -czvf backup.tar.gz /data,参数记法是:-c创建,-z用gzip,-v显示过程,-f指定文件名(-f必须紧挨文件名,放最后最安全)。解包是tar -xzvf backup.tar.gz,-C /target指定解到哪个目录。只查看内容不解包,用tar -tzvf。

-j换成bzip2、-J换成xz,压缩率更高但更慢。前端和后端同学经常要在服务器上解压前端构建产物,unzip dist.zip -d /usr/share/nginx/html,-d指定目录,-o覆盖已有文件不提示。

这里有个巨坑:unzip默认不会保留Linux下的可执行权限,解压出来的脚本可能没有x位,得手动chmod +x。而zip打包时如果不带-X也会丢权限属性。所以跨系统传可执行文件,我更倾向用tar.gz,它在Linux之间对权限保留更友好。

5.2 中文乱码的成因与解决

"Linux解压文件乱码"这个词搜的人特别多,但原因其实很单一:Windows在打包zip时默认用GBK编码存文件名,而Linux的locale通常是UTF-8,两种编码对不上,中文名就变成一堆问号或方块。

解决办法有几个,按优先级排:

unzip -O CP936 file.zip # 指定用GBK解析文件名(部分版本支持) unzip -O GBK file.zip 7z x file.zip # p7zip通常能自动识别,最省心

如果unzip版本不支持-O,最稳的是装p7zip,用7z x解压,它内部会尝试检测编码。已经解压出一堆乱码文件名要补救,可以用convmv -f GBK -t UTF-8 -r --notest .批量改文件名。对于文件内容本身的乱码(不是文件名),用iconv -f GBK -t UTF-8 in.txt > out.txt转编码。

根治办法是统一编码规范:项目里所有文本文件一律存UTF-8,Windows编辑器里显式选UTF-8而不是"ANSI"或"GB2312"。我在团队里把这条写进了代码规范,省了后面无数麻烦。

注意:convmv默认只做演练不实际改名,要真正执行必须加--notest。先不加跑一遍看输出,确认无误再加,这是它的安全设计,别嫌麻烦。

5.3 传输与校验:别让文件在传输里悄悄坏掉

跨机器传文件,小文件直接scp,大文件用rsync -avzP,-P会显示进度并支持断点续传,比scp重传整个文件强太多。rsync的-a等于-rlptgoD,保留符号链接、权限、时间、属主属组,是"归档模式",做数据同步基本都用它。

传完不放心,用md5sum或sha256sum校验:

md5sum bigfile.iso > bigfile.md5 md5sum -c bigfile.md5 # 校验

前面提到的"再生龙备份Linux系统"这类整盘镜像,校验这一步不能省,出错的文件恢复出来是坏的,等到真要用的时候才发现就晚了。镜像本身也建议先sha256sum核对官方值再刻盘或写入。

6. 用户、服务与定时任务:日常运维的三块积木

6.1 用户与权限管理:useradd 那点事

useradd -m -s /bin/bash tom创建用户并建家目录、指定shell。不加-m家目录里没有骨架文件,登录后连.bashrc都没有,环境变量一团乱,这是新手常犯的错。passwd tom设密码,usermod -aG sudo tom把用户加进sudo组,-a必须带,不加会覆盖用户已有的其他附加组——这个-aG里的a是append,漏了它后果很严重,用户的组权限会被清空只剩这一个。

id tom看用户的UID、GID和所有附加组,groups tom看组,whoami看当前用户,su - tom完整切换用户(带-会加载目标用户环境),sudo -i提权到root。批量授权时用visudo改sudoers,而不是手动编辑/etc/sudoers,因为visudo会做语法检查,写错了不至于把系统搞成谁都不能sudo。

6.2 systemctl:服务管理的新标准

老系统用service和chkconfig,现在主流发行版都是systemctl:

systemctl start nginx # 启动 systemctl stop nginx # 停止 systemctl restart nginx # 重启 systemctl reload nginx # 重载配置,不中断服务 systemctl status nginx # 看状态和最近日志 systemctl enable --now nginx # 设开机自启并立即启动 systemctl disable nginx # 取消自启

reload和restart的区别值得说:reload让服务重新读配置但不重启进程,理论上不中断现有连接;restart是彻底停再起,会有短暂中断。nginx、redis都支持reload,改完配置优先试reload。status里的Active和Loaded两行能看出服务是否在运行、开机自启是否配好,journalctl -u nginx -f跟踪某个服务的实时日志,比翻日志文件方便。

6.3 crontab:定时任务的五个星号

crontab格式是分 时 日 月 周 命令,五个字段从左到右:

0 2 * * * /bin/bash /opt/backup.sh >> /var/log/backup.log 2>&1

意思是每天凌晨2点执行备份脚本,输出追加到日志文件并同时捕获错误输出。>> ... 2>&1这个写法非常重要,不写的话cron的输出会试图发邮件,服务器上没配邮件系统时任务可能静默失败,你连错在哪都看不到。

每个用户有独立的crontab,crontab -l列出、crontab -e编辑、crontab -r删除(这个删除全部,慎用)。/etc/crontab和/etc/cron.d/下的是系统级的,多一个用户名字段。cron任务不执行,九成是三个原因:环境变量PATH和交互式shell不同(脚本里全用绝对路径能解决)、脚本没有可执行权限、时间字段写错了。

7. 高频Linux面试题速查与答题思路

7.1 命令类问题:答细节,别只答名字

下面这张表是我整理的高频命令题,右侧是我建议的答题方向。记住一个原则:面试官问"XX命令怎么用",往往想听的是参数和适用场景,而不是"它就是用来干XX的"。

面试问题建议答题方向
如何查看某端口被谁占用ss -tunlp 或 lsof -i,解释 -n 避免DNS反查
如何实时查看日志最后100行tail -f -n 100,说明 -f 跟随新内容,退出用 Ctrl+C
软链接和硬链接的区别硬链接共享inode、不能跨文件系统;软链接是独立文件、可跨系统、可指向目录
如何找出大文件du -ah --max-depth=1 加 sort -rh,或 find -size +100M
杀掉进程的几种方式kill -15 优雅、-9 强制,为什么优先15
df 和 du 结果不一致删除但未释放句柄的文件,lsof grep deleted
如何统计文件行数wc -l,加 grep -c 说明区别

tail -f和tail -F也常被一起问。-f只跟随当前文件,日志轮转后tail跟着的还是旧文件(虽然文件被改名了);-F会检测文件名重新打开,日志切割后仍能继续跟新文件。生产上看日志我更推荐tail -F。

7.2 场景类问题:讲清你的排查顺序

场景题才是拉开分差的地方。比如"服务器负载突然很高,你怎么办",背命令没用,面试官要看你的排查逻辑。我一般这么答:先用uptime或top确认负载多高、什么时候开始的,再看top里是哪个进程占CPU,是用户态还是内核态;如果CPU不高但负载高,就往IO和不可中断进程查,iostat -x看磁盘%util,ps -eo state,pid,cmd | grep "^D"找D状态进程。整个过程是"先定位层次,再定位进程,最后看进程内部",层层收敛。

再比如"程序启动报端口被占用",标准回答:ss -tunlp | grep 端口找到PID,ps -p PID -o pid,ppid,cmd看是什么进程和它的父进程,判断是残留的旧实例还是别的服务。如果是旧实例,先kill -15,观察是否退出,不行再-9。答的时候带上具体命令,比空谈"我会找到那个进程然后杀掉"有说服力得多。

7.3 排查类问题:把"遇到过"讲成"解决过"

面试里最加分的是讲一个你自己排过的问题,有起点、有弯路、有结论。比如我常讲的一个:某次磁盘写满,df -h显示/满了,但du -sh /*加起来对不上。我先怀疑是日志,du排除了;再用lsof | grep deleted找到几个被删除但句柄没释放的日志文件,占用了几十个G;最后重启对应服务,空间回落。这个案例能顺带讲出df和du的差异、lsof的用法、以及为什么"删了文件空间没释放"。

讲这类问题时,把中间走过的弯路也说出来,反而更真实。面试官不怕你不会,怕的是你"遇到过"但说不清怎么排查的,那说明当时是别人帮你解决的。

8. 我踩过的坑和几条私藏经验

练命令这件事,光看不练等于没学。我刚开始的时候背了一堆参数,真上服务器还是手忙脚乱。后来我逼自己在本地虚拟机里反复练:新建用户、配权限、跑定时任务、故意把磁盘写满再救回来。摔过几次之后,命令才真正长在手上。下面几条是我觉得最值钱的。

第一,永远假设你的rm会打偏。前面说的echo替代法、${DIR:?}写法、alias rm='rm -i',三招一起上。我见过一次线上误删,就是因为脚本里cd没成功,结果在错误的目录里执行了rm -rf *。

第二,日志和临时文件一定要有清理策略。logrotate该配就配,临时目录用find /tmp -type f -mtime +7 -delete定期清。磁盘满不是"会不会"的问题,是"什么时候"的问题,早做准备比事后救火轻松太多。

第三,把命令写进脚本时,开头加set -euo pipefail。-e遇到错误就退出,-u用未定义变量报错,-o pipefail让管道中任一环节失败都算失败。不加这几行,一个中间步骤失败了脚本还在往下跑,最后产出个半成品你还不知道。

第四,别迷信"一条命令解决一切"。可读性比炫技重要,脚本是给三个月后的自己和同事看的。一条能用但没人看得懂的awk,不如拆成三条普通的命令加注释。

最后分享个查命令用法的小习惯:man太啰嗦的时候,先试命令 --help,大多数命令的短参数都能看到;tldr这个工具更直接,给几条常见示例,tldr tar比翻man页快得多。这些工具用顺手了,你的命令查得快、记得也牢。我到现在遇到不熟的参数,第一反应还是先--help看一眼,再动手。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询