先把结论放前面:Linux的基本指令不是背出来的,是“用”出来的。我见过太多人抱着一长串命令列表背两天,结果到了真机上连ls -l输出里那一堆字段都看不懂,更别提grep、awk、tar这些每天都在用的组合。这篇文章我换个思路,不按“命令大全”的方式罗列,而是把基本指令拆成几个真实的使用场景,从场景反推命令,顺带把参数的含义、易踩的坑、排查的思路一起讲清楚。无论你是刚接触Linux的新手,还是准备运维面试、想补嵌入式Linux基础的工程师,这篇都能帮你把“会用”变成“用得明白”。
1. 先给基本指令分个类:别让命令列表吓住你
Linux命令数量多到吓人,随便一个发行版里都有上千个可执行文件。但实际日常使用中,你真正高频调用的基本指令就那么几十个。我自己的习惯是先把命令按用途分成六类,再往里填具体命令,这样记忆负担会小很多。
第一类:目录与文件操作。cd、ls、pwd、mkdir、rm、cp、mv、ln,这一类占日常操作的一半以上。
第二类:文件内容查看与检索。cat、less、tail、head、grep、sed、awk,做日志分析、文本处理时全是它们。
第三类:权限与用户管理。chmod、chown、useradd、passwd、sudo、su,多人协作和服务器管理绕不开。
第四类:进程与服务管理。ps、top、kill、systemctl、free,排查系统负载、服务异常时靠这一组。
第五类:网络、磁盘与系统状态。ss、netstat、ping、df、du、uname,日常体检服务器状态的时候用。
第六类:归档压缩与文件传输。tar、zip、scp、rsync,部署、备份、迁移的必备工具。
之所以先分类,是因为命令之间的关联性比孤立记忆重要得多。比如你看到ls的时候,如果能联想到ls -l、ls -a、ls -lh,并且知道什么时候该用哪个,比背下三十条ls参数更有价值。面试里也常考“Linux常用命令大全”,但面试官其实在意的不是你会列多少条,而是你知不知道在什么场景下选哪条命令、为什么选它。
2. 目录与文件操作:在Linux里“走路”和“搬东西”的基本功
2.1 cd、ls、pwd:先学会看清楚自己在哪
很多人用Linux的第一天就在cd和ls上吃了亏。pwd是最容易被忽略却最实用的命令之一,它告诉你当前所在的目录。每次连接服务器、切换用户或者跑完一个脚本,先敲一句pwd,确认自己没跑偏,这是最基础的操作习惯。
cd的用法里有几个隐藏细节。cd ~回到当前用户的家目录,cd -回到上一次所在目录,这两个快捷方式能省很多事。绝对路径和相对路径的区别也必须搞清楚:绝对路径从根目录/开始写,比如cd /var/log/nginx;相对路径从当前位置开始写,比如cd ../conf。我见过不少新手在脚本里写了相对路径,结果脚本被放到另一个目录下执行就直接崩了,这就是没搞懂两者的本质区别。
ls的常用参数用一句话就能记牢:ls -l看详细信息,ls -a看隐藏文件,ls -h把文件大小显示为人类友好的单位,ls -t按时间排序,ls -S按大小排序。实战里用得最多的组合是ls -lht,按时间列出当前目录下所有文件并显示大小,排查日志目录时特别好用。
ls -l的输出很多人只会看第一列和最后面的文件名,中间那一串其实信息量很大。比如下面这行:
-rw-r--r-- 1 root root 2351 Feb 20 10:30 app.log从左到右依次是:文件类型和权限、硬链接数、属主、属组、大小、最后修改时间、文件名。文件类型里,-是普通文件,d是目录,l是软链接,c是字符设备。把这些看懂,你就已经超过了相当一部分“背过命令但不会看输出”的人。
2.2 创建、复制、移动、删除:胆大心细的操作合集
创建文件和目录很简单:touch test.txt创建空文件,mkdir mydir创建目录,mkdir -p a/b/c则可以连同中间层级的目录一起创建。这个-p在很多命令里都是“递归、自动补齐父级”的意思,cp -r里的-r也是一样。没有-p的时候,mkdir a/b/c会报No such file or directory,新手尤其容易在这里卡壳。
cp和mv的区别要刻在脑子里:cp是复制,原文件还在;mv是移动或重命名,原位置就没有了。跨文件系统移动时,mv的行为会退化成“先复制再删除”,所以大批量移动文件时如果发现速度异常,别太意外。复制目录必须加-r,即cp -r src_dir dest_dir,否则会提示-r未指定而失败。
删除指令rm是世界上最快让人后悔的命令,没有之一。rm file删普通文件,rm -r dir删目录,rm -f是强制删除不提示,rm -rf则是“递归+强制”,瞬间能把整个目录树干掉。我从来不建议新手把rm -rf当成顺手敲的指令,尤其不要在写脚本的时候裸用变量拼路径,比如rm -rf $DIR/,一旦$DIR为空变成rm -rf /,后果直接是灾难级的。真要用,先把路径写死,再在命令前加echo打印出来检查一遍。
2.3 软链接与硬链接:被面试问烂的ln
ln -s创建软链接(符号链接),ln不带参数创建硬链接。软链接可以跨文件系统,也可以指向目录,但它本质是个指向原路径的文件,原文件被删掉后软链接就失效了。硬链接不能跨文件系统,不能指向目录,但它和原文件共享同一个inode,只要还有一个硬链接存在,数据就还在。
实际工作中,软链接的使用频率远高于硬链接。比如在嵌入式Linux里,/usr/bin/python常常是/usr/bin/python3的软链接,这样上层脚本不用关心具体版本。面试题里常问“软链接和硬链接的区别”,把这两段说清楚,再顺带提一下inode,基本就是满分回答。
3. 文件内容查看与文本检索:日志排查的全套手艺
3.1 从cat到less:只看需要的内容,不要一次全倒出来
cat适合查看小文件,一般几百行以内的配置文件用cat没问题。但大文件千万别用cat直接刷屏,打开一个几百MB的日志,终端会卡到像死机。这时候用less,支持上下翻页、按/搜索关键词、按q退出,基本是日志查看的标配。
tail和head是只查看文件开头或结尾的命令。tail -n 50 app.log表示看最后50行,tail -f app.log是实时跟踪文件新增内容,排查线上日志时这就是主力命令。head -n 20看文件开头,经常用来快速确认日志格式或者配置文件的前几行。
这里有个实用技巧:排查日志时,先tail -n 100 app.log | grep 'ERROR'过滤出错误行,再用sed -n '10,20p' app.log按行号区间打印某一段内容。这两个组合用下来,基本能应对绝大多数日志定位需求。
3.2 grep:文本检索的核心力量
grep是最值得吃透的命令之一。最基本的用法是grep keyword file,在文件里搜关键字。实际使用中我几乎总是带参数:
grep -i忽略大小写;grep -v反向匹配,排除掉某些行;grep -r递归搜索目录,排查代码里的调用关系很好用;grep --include='*.conf'限定只搜索.conf文件;grep --exclude='*.log'跳过日志文件。
正则表达式是grep的进阶玩法。基础正则里,^匹配行首,$匹配行尾,.匹配任意单个字符,*匹配前一字符零次或多次。加grep -E后可以使用扩展正则,+、?、|、{}这些元字符就能直接用了。比如查IP地址:grep -E '[0-9]{1,3}(\.[0-9]{1,3}){3}' access.log。
我自己的习惯是:先在head输出里确认日志格式,再设计正则,最后用小范围样本验证,不会直接拿大文件跑一个自己都拿不准的正则。
3.3 sed和awk:文本处理的“三板斧”入门
很多人一听sed和awk就发怵,实际上日常用到的功能非常集中。
sed主要用于替换和删除。替换的格式是sed 's/old/new/g' file,其中g是全局替换,不加g只替换每行第一个匹配。sed '/pattern/d' file可以删除匹配特定模式的行。注意sed默认不会修改原文件,要想直接在文件上生效要加-i,比如sed -i 's/127.0.0.1/0.0.0.0/g' app.conf。这个-i要格外谨慎,因为修改是回不来的,建议先不加-i跑一遍把结果打到终端检查。
awk的核心功能是按列处理文本。默认按空格或Tab分隔,awk '{print $1, $3}' file就能打印第一列和第三列。比如从ls -l的输出里提取所有文件大小,可以用ls -l | awk '{print $5}'。再加一点条件判断,awk '$5 > 1024 {print $9}',就能筛选出大于1KB的文件名。awk真正强大的是后面还能挂BEGIN、END这些块,执行累加统计之类的操作,但入门阶段把“按列提取+条件过滤+打印”这三件事练熟就完全够用。
4. 权限与用户管理:每个符号后面都是事故教训
4.1 看一眼权限位,就知道会不会被拒绝
ls -l输出第一列的十个字符里,第一个是文件类型,后面九位分成三组,分别代表属主、属组和其他人的权限。每一组三位,顺序是读、写、执行。rwx都出现就是7,rw-就是6,r-x就是5,r--就是4。这套数字换算一定要熟到像条件反射一样:
- 755:属主可读写执行,属组和其他人可读可执行,常用于目录和可执行程序;
- 644:属主可读写,其他人只读,常用于普通文件;
- 600:只有属主可读写,常用于密钥、密码文件;
- 700:只有属主可读可写可执行,常用于私密脚本目录。
chmod可以直接用数字,也可以符号方式。chmod u+x script.sh给属主加执行权限,chmod g-w file去掉属组的写权限。实际部署时,我倾向于先想想这个文件到底要给多少人什么权限,再决定用哪个数字,而不是无脑复制网上的chmod 777。chmod 777在公网服务器上就是给所有用户开放写权限,安全风险极大,能用755、644解决的问题绝对不用777。
4.2 修改属主和属组:chown的规范用法
chown user:group file可以同时修改属主和属组,比如chown nginx:nginx /var/www/html。有时候只需要修改属组,可以用chgrp,不过chown user:group一条命令都能搞定,我自己基本不怎么单独用chgrp。目录递归修改时,chown -R user:group dir会连目录下所有子文件和子目录一起改,执行后最好用ls -l抽查几个文件确认没有问题。
有一个很容易被忽略的细节:修改配置文件的属主时,如果网站用的是Nginx和PHP-FPM,不同进程要求不同的读权限。前端静态文件给Nginx用户读就行,PHP文件可能需要PHP-FPM用户读,日志目录往往要交给某个服务用户写。盲目地chown -R www:www处理一切,后续可能会出现奇怪的权限报错,遇到这种问题第一步就是检查属主属组对不对。
4.3 用户管理:useradd、passwd、sudo和su的区别
useradd用来新建用户,useradd -m -s /bin/bash alice创建用户并创建家目录、指定登录Shell。passwd alice设置密码。useradd和adduser的区别是不同发行版对后者的封装不同,在Debian系的系统里adduser更像交互式向导,在CentOS/Rocky里两者行为也有差异。建议直接掌握useradd,表现更稳定。
su和sudo都要会用,但用法差异很大。su - root是切换到root用户,需要输入root密码,整体环境变量也切到root的;sudo command是临时用root身份执行某条命令,输入的是当前用户的密码,前提是当前用户被加入了sudo权限组。
生产环境里我最推荐的做法是:不给任何人root密码,日常管理全部通过sudo完成,需要提升权限时用sudo visudo精确控制,只给指定用户授权几条命令。比如:
devuser ALL=(ALL) /usr/bin/systemctl restart nginx这样只允许devuser执行重启Nginx的操作,其他root权限一律不给,是降风险非常实用的做法。另外,sudo -u anotheruser command是以某个指定用户身份执行命令,这条在排查“为什么这个程序没权限”时特别有用。
5. 进程、服务与系统状态:一眼看出机器到底怎么了
5.1 ps、top、free:先看有没有“坏人”占资源
排查一台变慢的服务器,我不会上来就重启,而是先跑三连:top、free、df -h。
top是动态查看进程和系统负载的利器。第一行能看到负载均值,三个数字分别代表1分钟、5分钟、15分钟平均负载,如果持续高于CPU核心数,说明系统确实繁忙。按下P键按CPU排序,按下M键按内存排序,q退出。
ps则是静态打快照的视图。日常够用的组合是ps aux或ps -ef,配合grep筛选进程,比如ps aux | grep nginx。ps输出里的STAT列很关键,S表示睡眠,R表示运行,Z表示僵尸进程。如果看到很多Z,说明父进程没有回收子进程资源,这是一条重要的排查线索。
内存方面输出free -h,重点看available那一列。这里有个常见认知偏差:free的used看起来很高并不代表内存不够,因为Linux会把空闲内存用作缓存,实际可用的是available,数值才真正反映还有多少内存可以用来分配。
5.2 kill、systemctl:系统服务管理的两套思路
杀掉一个进程,常用kill PID,默认发的是SIGTERM信号,让进程自己清理后退出。如果进程不响应,才用kill -9 PID强制杀掉。这里要特别提醒:kill -9不要一上来就使,有些程序被强制杀掉后,缓存数据没落盘,直接会损坏文件。
systemctl start/stop/restart nginx是管理系统服务的方式。改完配置文件后,需要systemctl daemon-reload让systemd重新加载配置,再systemctl restart nginx生效。排查服务状态时,systemctl status nginx会显示进程PID、最近日志和当前状态,比单纯用ps判断“进程在不在”信息量更大。
实际运维里,我遇到更多的情况是这样:进程明明还在,但服务就是访问不了。这时候优先查端口监听状态,再看日志输出,一步步缩小范围,而不是直接重启大法。
5.3 ss和netstat:端口的真相都在这
排查端口监听,老派命令是netstat -tlnp,现在很多新系统里更推荐ss -lntp,原因是大数据量连接下ss更快。
ss -lntp里的参数含义是:-l只看监听状态的端口,-n不做域名反解直接显示数字,-t只显示TCP连接,-p显示进程信息。输出里如果看到0.0.0.0:80,说明这个端口监听在所有网卡上;127.0.0.1:3306则只监听本机回环地址,外部无法访问。很多数据库默认只允许本机连接,外部连不上时先查这里就会发现原因。
查看完整连接状态时,还能看到ESTAB、SYN_SENT、TIME_WAIT等状态。如果出现大量的SYN_SENT连接,往往意味着目标端口不通或者防火墙拦截;TIME_WAIT过多,一般跟短连接高并发有关。这些状态背后都对应着典型的网络故障模型,值得单独记一下。
6. 归档压缩与文件传输:部署和备份的基本功
6.1 tar:一条命令搞定打包和压缩
tar命令的常用组合基本是固定的:
# 打包压缩 tar -czvf backup.tar.gz /var/www/html # 解压 tar -xzvf backup.tar.gz # 解压到指定目录 tar -xzvf backup.tar.gz -C /tmp/restore参数拆开理解:-c创建归档,-x解压,-z使用gzip压缩,-v显示过程,-f指定归档文件名。为什么-f总是放在最后?因为-f后面跟着的是文件名,如果写成tar -cfz,f后面会被当成文件名的开头,命令就会错乱。
有几个实用变体也要记住。打包时排除某些文件:tar -czvf backup.tar.gz --exclude='*.log' --exclude='cache' /var/www/html。只查看归档内容不解压:tar -tzvf backup.tar.gz。处理.tar.gz时用-z,处理.tar.bz2时用-j,处理.tar.xz时用-J。
6.2 scp和rsync:传文件别只靠rz/sz
复制文件到远端服务器,scp file user@host:/path是最直接的方式。递归复制目录需要加-r,指定端口则加-P。scp -P 2222 app.tar.gz root@192.168.1.10:/opt/。
rsync则更强大,它最大的价值是增量同步:只传输差异部分,文件多的时候性能优势明显。基本用法rsync -avz src_dir/ user@host:/dest_dir/,其中-a保留权限、属主、时间戳等元信息,-v显示过程,-z传输时压缩。注意src_dir/和src_dir末尾的斜杠有个坑:带斜杠表示同步目录里的内容,不带斜杠会把目录本身也同步过去。这个细节不搞清楚,经常会把目录层级同步错。
rsync加--delete可以删除目标目录里源端没有的文件,让两边完全一致,但这条参数一定要经过演习再用,因为误删是无法挽回的。备份场景里我更常用的是rsync -avz --backup配合备份目录,避免覆盖旧文件。
7. 我这些年踩过的坑:Linux基本指令现场实战笔记
7.1 命令找不到,先检查PATH和环境变量
新装的Linux系统里,有些命令输入后提示command not found,第一反应不是“命令不存在”,而是确认它是不是有名但不在PATH里。比如ifconfig在较新发行版上默认不存在,替代者是ip addr;netstat不在的话可以用ss。真需要安装时,Debian系执行apt install net-tools,RHEL系执行dnf install net-tools。
echo $PATH可以查看当前在哪些目录里找命令。如果自己安装的软件,比如Python或Node,装完还是执行不了,大概率是它的可执行目录没有加进PATH。修改/etc/profile或者当前用户的~/.bashrc,然后source生效。这类问题在面试题的实践环节经常出现,不要只背命令,要真的动手装一次。
7.2 rm之后后悔了:别慌,先说预防方案
删除文件之后才发现自己删错了,如果是用普通方式删的,在大部分情况下已经没法直接恢复。能救的可能是临时占用情况下的文件句柄,但那需要进程还在运行的特殊场景。现实做法是提前备份,或者在操作前用mv把文件移到临时目录而不是直接rm。
我现在养成了一个习惯:在删除目录前,先执行ls -la看清目录里有什么,再执行du -sh看清目录大小,最后把完整的路径拼好,用echo打印一下确认无误再真的执行。禁止在环境变量没有验证的情况下使用rm -rf $VAR/这种写法。这不是胆小,是吃过亏以后的肌肉记忆。
7.3 磁盘显示没问题,但还报No space left
df -h显示使用率不高,但系统仍然提示磁盘空间不足,这种情况大概率是inode耗尽了。df -i可以查看inode使用率,如果到100%,即使还有剩余块也无法新建文件。出现这种情况,通常是某个目录下堆积了大量小文件,比如邮件队列、缓存目录或者/tmp下的碎片。定位方法是对每个目录执行find / -xdev -type f | wc -l对比统计,找到文件最多的目录再做清理。
另一个常见坑是删除了文件但空间没释放。原因是文件被某个进程占用,删除后空间要等进程关闭文件句柄才释放。用lsof | grep deleted找出这些文件对应进程,重启该进程后空间就能正常回收。
7.4 端口占用:除了换端口,还要找到谁占的
服务启动时报Address already in use,先查谁占了这个端口:lsof -i:8080或者ss -lntp | grep 8080。查到PID后,用ps -fp PID看是什么进程。如果确认是残留的旧服务,可以kill PID清理;但如果不是你的服务,不要看到端口就是杀,先确认进程归属,避免误伤。
7.5 权限被拒:Permission denied的万能排查顺序
遇到权限相关的报错,我从来不慌,按顺序排查基本都有答案。第一步ls -ld看完文件类型和权限,第二步确认当前用户和文件属主属组,第三步检查父目录有没有执行权限,第四步看是否有SELinux或AppArmor策略在拦截。
比如网页目录里文件权限明明是644,但Nginx就报Permission denied,被忽略的往往是父目录没有执行权限。没有--x权限时,即使文件可读,也无法通过父目录进入访问路径。SELinux开启时会出现更隐蔽的拒绝,先getenforce确认SELinux状态,再用ausearch -m avc -ts recent查看拒绝日志,比盲目chmod 777靠谱一百倍。
7.6 常用命令速查表:贴键盘旁边,比收藏夹好用
| 场景 | 命令 | 备注 |
|---|---|---|
| 查看当前路径 | pwd | 脚本里建议先执行 |
| 查看文件详情 | ls -lht | 按时间排序 |
| 递归创建目录 | mkdir -p a/b/c | 自动补父目录 |
| 查找文件 | find /path -name '*.log' | 按文件名检索 |
| 搜索文件内关键词 | grep -rn 'error' /var/log/ | 递归加行号 |
| 实时看日志 | tail -f app.log | 排查线上问题主力 |
| 复制目录 | cp -r src dest | 别漏-r |
| 移动或重命名 | mv old new | 测试环境可用,生产慎用 |
| 删除目录 | rm -rf | 用前先echo拼好路径 |
| 打包目录 | tar -czvf backup.tar.gz dir | 排除文件用--exclude |
| 解压 | tar -xzvf backup.tar.gz -C target | -C指定目录 |
| 查看端口 | ss -lntp | 替代netstat |
| 查看进程 | ps aux | grep nginx | 加-ef展示全格式 |
| 实时状态 | top | P按CPU排序,M按内存排序 |
| 修改权限 | chmod 755 script.sh | 普通文件用644,脚本用755 |
| 修改属主 | chown -R user:group dir | 递归需确认 |
最后再分享一个我自己的习惯:每一个命令敲下去之前,先在心里回答三个问题——我现在在哪个目录?这条命令要操作的文件全路径是什么?操作能不能撤销?三个问题都答得上来,再按回车。这听起来慢,实际上比敲错以后花半小时排查要快得多。把这些指令内化成条件反射以后,你再看Linux基本指令,就不是一堆零散的命令,而是一张随时能调用的解决问题的地图。