2. Linux 基本指令进阶实操记录
先说一个我自己的感受:很多人学 Linux 指令,第一遍看完 ls、cd、cat 就觉得“我会了”,但真到了自己搭环境、传文件、排查问题的时候,又不知道该用哪条命令。这一篇是接着上次的基础指令往下走的,重点放在你日常工作中真正高频、真正能帮你省时间的那批指令上——文件操作、文本查看、用户权限、网络传输、日志排查、软件安装,基本覆盖了一个 Linux 使用者从“知道命令”到“能干活”的跨越阶段。
这篇内容适合两类人:一类是刚接触 Linux、想在真实场景里把指令用起来的新手;另一类是已经会一些基本操作,但遇到“删除文件夹”“查看端口占用”“远程传文件”这类具体问题还要临时搜的人。我会把每条指令放在实际场景里讲,告诉你为什么要这么用、踩过哪些坑、生产环境里一般怎么组合使用,希望你看完能直接拿去用。
1. 从“会用”到“会选”:Linux 指令学习的关键思路
1.1 为什么记了那么多命令,用的时候还是卡壳
很多初学者有个误区,以为学 Linux 就是背命令。其实命令本身不难查,难的是“知道在什么场景下选哪条命令”。我见过不少人把 ls -l 的每一项都背得滚瓜烂熟,但遇到“磁盘满了”还是不知道先 df -h 再 du -sh,遇到“服务起不来”也不知道去看日志文件。
这里的关键是:要把指令按“用途场景”分类理解,而不是按字母顺序去背。比如文件相关的指令,核心就这几个动词:创建(touch/mkdir)、复制(cp)、移动(mv)、删除(rm)、查找(find)、查看内容(cat/less/tail)。你只要在大脑里建一个“我想干什么 → 用哪条命令”的映射,比死记硬背高效得多。
我自己带团队的时候,经常跟他们说一句话:不要追求“我会很多命令”,要追求“给我一个真实任务,我能用最少的时间完成它”。这也是这篇博文贯穿始终的编写逻辑——每条命令都尽量放在真实的操作场景里来解释,而不是单拎出来讲参数。
1.2 命令自带的帮助信息,才是你最该依赖的文档
在进入具体指令之前,我想强调一个很容易被忽略的能力:查看帮助。很多人遇到不熟悉的命令,第一反应是打开浏览器搜索,但 Linux 本身自带的帮助信息往往足够用,而且更精准。
man 命令名:查看完整的操作手册,比如man ls,里面把每个参数的解释、示例都写得很清楚。命令名 --help:大多数 GNU 工具都支持这个参数,会输出精简版的用法说明,比 man 更快。info 命令名:有些命令的文档在 info 里比 man 更详细。
我实操中最常用的是 --help,因为 man 手册太长了,很多时候我只想知道某个参数怎么写,--help 一两屏就够。但如果是研究一个命令的全部能力,比如 find 的复杂用法,那必须老老实实翻 man find。
提示:不确定某条命令是否存在时,可以用
which 命令名或type 命令名来查看路径;查不到路径一般说明这个命令没安装,需要先装对应的软件包。
2. 文件与目录操作进阶:从“会删”到“会找”
2.1 删除文件夹的正确姿势:rm -rf 到底能不能用
删除文件或目录是最基础的操作,网上关于 rm -rf 的段子一大堆。现实里,删除文件夹最常见的需求是清空某个项目目录或者临时目录,命令是:
bash复制rm -rf /path/to/directory
r表示递归删除,也就是把目录里所有子目录和文件都删掉。f表示强制删除,不逐一确认。
但这里我必须说清楚:rm -rf 不是不能用,而是用的时候必须有确定的目标。我见过不少事故都是路径变量为空导致的,比如脚本里写了 rm -rf $DIR/*,但 $DIR 因为某些原因没赋值,最终执行成了 rm -rf /*,后果可想而知。
所以我自己在使用 rm -rf 时有几条铁律:
- 绝对路径写全,不要只依赖相对路径,至少眼睛能看到“我要删的是哪个目录”。
- 在交互式终端里,先
ls看清目录内容,再执行删除。 - 如果是在脚本或生产服务器上操作,删除前先备份,或者用
mv把目录移动到 /tmp 下,确认没问题再删。 - 回收站思路:可以先
mv 目标目录 ~/.trash/,定期统一清理,比直接 rm 稳妥得多。
另外,rm 删除的文件是找不回来的,连恢复工具都很难救。所以涉及重要数据,别碰 rm,老老实实先备份。
2.2 查找文件:find 命令的几个实用维度
热词里 “linux find” 出现频率很高,说明很多人对这个命令停留在“知道但不会写”的阶段。find 的作用是在目录树中查找文件,它的强大之处在于可以按照文件名、类型、大小、时间、权限等多个维度组合搜索。
最简单的用法:
bash复制# 在当前目录下查找所有 .conf 文件
find . -name "*.conf"
# 在 /var/log 下查找所有 .log 文件
find /var/log -name "*.log"
但真正实用的是高级组合。比如:
bash复制# 找到 /home 下大于 500MB 的文件
find /home -type f -size +500M
# 找到最近 7 天内修改过的文件
find /var/www -type f -mtime -7
# 找到 30 天前访问过的日志文件,并删除
find /var/log -type f -atime +30 -exec rm {} \;
这里要注意 -exec 后面的格式:{} 会被替换为每个匹配到的文件路径,\; 表示命令结束。很多人第一次写 -exec 时漏掉最后的 \;,会直接报错或者执行失败,这是个很典型的坑。
还有一个常被忽略的选项是 -maxdepth,它用来限制递归深度。如果目录树很深,你又只想看第一层,可以写:
bash复制find . -maxdepth 1 -name "*.conf"
不加限制的话,find 会扫完整棵树,文件多的时候会非常慢,这也是新手很容易犯的毛病。
2.3 软链接与硬链接:ln 指令的原理和使用场景
ln 用来创建链接,分软链接(符号链接)和硬链接两种。软链接更像是 Windows 里的快捷方式,指向的是路径,目标被删掉后链接就失效了;硬链接指向的是文件的 inode,相当于同一份文件的另一个入口,原文件被删掉后硬链接依然能读到内容。
创建软链接最常用的场景是解决“路径迁移”问题。比如某个应用要求配置文件必须放在 /etc/myapp/config.ini,但实际配置文件我保存在 /data/config/config.ini,这时候可以:
bash复制ln -s /data/config/config.ini /etc/myapp/config.ini
这样应用读 /etc/myapp/config.ini 时实际读到的是 /data/config/config.ini。用软链接的好处是,以后只要替换 /data/config/config.ini,所有引用到这个路径的应用都会自动更新,不需要改动业务代码。
硬链接我平时用得少,但它有个实际价值是备份场景。比如 ln /var/log/nginx/access.log /backup/access.log.bak,在同一个文件系统内,硬链接不占用额外数据空间,还能防止原文件被覆盖后内容丢失。
注意:软链接可以跨文件系统,硬链接不可以。硬链接也不能对目录创建(软链接可以)。排查链接问题的时候,用
ls -l查看,软链接会显示->指向的真实路径。
3. 文本查看与内容处理:日志排障的必备技能
3.1 tail 命令:动态跟踪日志文件
排查问题时最常用的指令之一就是 tail,尤其是 tail -f。它的作用是实时跟踪日志文件的新增内容。比如 Nginx 出问题了,你可以:
bash复制tail -f /var/log/nginx/error.log
然后去浏览器或 curl 触发一次请求,日志会实时滚动出来,能直观看到报错信息。tail -f 在“观察服务启动是否正常”“确认请求是否打到这台机器”这类场景下,效率极高。
有时候日志文件已经写了很多,你想从 100 行开始看,可以:
bash复制tail -n 100 /var/log/nginx/error.log
如果想同时看头尾,可以用 tail 加 -n 再看,或者把两者合并使用:head -n 50 和 tail -n 50 组合,但更灵活的是用管道。
3.2 grep 与管道结合:在日志里精准定位
grep 是用来在文本中搜索关键词的,它和管道的组合是 Linux 下最经典的“过滤”手段。比如:
bash复制# 查看 Nginx 日志里所有 500 状态码的记录
grep " 500 " /var/log/nginx/access.log
# 查看所有包含 error 的进程
ps aux | grep error
# 查看所有 java 相关进程
ps aux | grep java
grep 支持正则表达式,所以它的表现力很强。比如我想看所有 4xx 或 5xx 状态码:
bash复制grep -E " [45][0-9][0-9] " /var/log/nginx/access.log
这里的 -E 表示使用扩展正则。如果你只是搜索普通字符串,不需要 -E。
另一个实用参数是 -C。grep -C 3 error app.log 会输出匹配行的前 3 行和后 3 行,在排查错误时能看到上下文,比只看一行报错信息有用得多。同理还有 -A(after,匹配后几行)和 -B(before,匹配前几行)。
很多日志文件非常大,直接 cat 出来会刷屏,正确的做法是用 grep 加上下文字段来精准地看,而不是把整个文件都输出出来。这也是排查线上问题时最基本的“少看多查”意识。
3.3 sed 文本处理:替换与打印的常见坑
热词里有 “linux sed 打印出来有乱码”,这个我遇到过不少次,先说现象:用 sed 处理包含中文或其他非 UTF-8 编码的文件时,输出可能会出现乱码。原因多半不是 sed 本身的问题,而是文件编码和终端编码不一致。比如文件是 GBK 编码,终端用的是 UTF-8,那么 sed 打印出来自然就是乱码。
解决思路有两类:
- 转换文件编码:用
iconv -f GBK -t UTF-8 文件名先转码,再交给sed处理。 - 调整终端编码,让终端和文件编码一致。
sed 最常用的能力是替换。基本格式是:
bash复制sed -i 's/旧内容/新内容/g' 文件名
其中 -i 表示直接修改文件,不输出到屏幕;s 是替换命令;g 表示全局替换。注意:如果不加 -i,sed 只是把修改后的内容输出到屏幕,并不会真正改文件。这个区别新手经常搞混,以为执行了就能改,结果发现文件纹丝不动。
另外还有一种常用操作是按行号打印:
bash复制# 查看第 10 到 20 行
sed -n '10,20p' 文件名
-n 表示“不自动打印每一行”,p 表示打印匹配的行。这个组合在查看配置文件的中间部分时非常顺手。
我在实际使用中还会配合 sed -i 去做批量配置文件修改,比如批量把 nginx 配置里的 localhost 全部换成 api.example.com,一条命令搞定几十个文件,比手动改效率高太多。
4. 用户管理与权限控制:不会被轻易绕开的核心问题
4.1 新建用户和设置密码的完整流程
热词里 “linux新建用户” 出现频率很高,这个需求通常出现在两种场景:一是给同事开服务器账号,二是为某个服务创建独立的运行用户。基本操作是:
bash复制# 创建用户 testuser
useradd testuser
# 设置密码
passwd testuser
这两条命令执行完,testuser 这个账号就能登录了。但如果你想让这个用户能正常使用 shell,并且有家目录,建议创建时带参数:
bash复制useradd -m -s /bin/bash testuser
-m表示创建家目录(/home/testuser)-s指定默认 shell,常见的登录 shell 是 /bin/bash
如果用户已经创建了,但之后想补一个家目录,可以手动创建并复制默认配置文件:
bash复制mkdir /home/testuser
cp -r /etc/skel/. /home/testuser/
chown -R testuser:testuser /home/testuser
/etc/skel/ 目录里放着新用户默认的隐藏配置文件(比如 .bashrc、.profile),手动建用户时别忘了复制一份,否则用户登录后可能没有命令提示符或环境变量异常。
删除用户的命令是 userdel,如果要连家目录一起删,加 -r:userdel -r testuser。
4.2 查看当前用户与提权操作:whoami、su、sudo
刚新建完用户,你可能会遇到一个问题:我想执行管理员权限的命令,怎么办?这就涉及到 Linux 权限模型里最常用的两个命令:su 和 sudo。
su - 用户名:切换用户,su -表示同时加载目标用户的环境变量。sudo 命令:以 root 权限执行单条命令。
实操中我几乎只用 sudo,因为 su 需要知道目标用户的密码,而且长期切换到 root 风险很大。sudo 只需要当前用户自己的密码,而且在 sudoers 文件里可以精确配置哪些用户能执行哪些命令,更安全。
查看当前身份用 whoami,查看当前用户 ID 和组用 id,这是排查权限问题时最先用到的两个命令:
bash复制whoami
id
很多“权限不够”的问题,根源就是执行命令的用户不对。你先 whoami 看一眼,如果是普通用户却去写 /root 或 /etc 下的文件,系统当然会拒绝。
4.3 改变文件归属和权限:chown 与 chmod 的生产实践
文件权限是 Linux 里一个绕不开的话题。ls -l 输出的第一列类似 -rw-r--r--,第一个字符表示文件类型(- 普通文件、d 目录、l 软链接),后面九个字符分三组:所有者、所属组、其他人,每组三位,分别表示读(r=4)、写(w=2)、执行(x=1)。
修改权限用 chmod,有两种方式:
bash复制# 数字方式:给所有者和同组用户加写权限
chmod 664 文件
# 符号方式:给组和其他用户去掉写权限
chmod go-w 文件
数字的规则是把 rwx 对应的值相加,比如 rwx = 7、rw- = 6、r-- = 4。所以 chmod 644 表示所有者可读写,组和其他人只读,这是最常见的文件权限设置。
修改归属用 chown,格式是 chown 用户:组 文件。比如把 web 目录的所有权给 nginx 用户:
bash复制chown -R nginx:nginx /var/www/html
-R 表示递归,目录里的所有文件和子目录都会一起改。在部署静态网站或者应用代码时,所有权不对经常导致“无法写入”或“403 没有权限”,排查思路就是先 ls -l 看归属,再 chown -R 设置正确归属。
注意:目录的执行权限(x)决定了你能否进入该目录。有时候文件权限是 644 但打不开页面,原因往往是父目录没有 x 权限,导致用户无法进入路径。排查时用
ls -ld 目录名查看目录自身权限。
5. 网络传输与远程操作:SCP、端口排查与连通性检查
5.1 用 scp 安全地远程传文件
热词里 “linux scp 命令” 排得很靠前,这个命令确实是我日常工作里使用频率最高的之一。它基于 SSH 协议,能在两台机器之间安全地复制文件。
基本用法:
bash复制# 本地文件传到远程服务器
scp /local/path/file.txt user@remote_host:/remote/path/
# 远程文件下载到本地
scp user@remote_host:/remote/path/file.txt /local/path/
# 递归复制整个目录
scp -r /local/dir user@remote_host:/remote/path/
几个常用参数:
-P 端口号(注意是大写 P):如果远程 SSH 端口不是默认的 22,需要指定,比如scp -P 2222 ...-i 私钥文件:指定密钥登录,比如scp -i ~/.ssh/id_rsa ...-r:递归复制目录-C:启用压缩,传输大文件时能明显加速
我在传输大文件时,还喜欢结合 rsync 来用,因为它支持断点续传和增量复制,比 scp 适合长时间任务。但对于简单的一两次文件传输,scp 足够用了。
注意:scp 如果中间网络不稳定,大文件传一半可能中断,而且不支持续传。生产环境传大文件,我更建议用 rsync -avP 源 目标,其中 -P 同时开启进度显示和断点续传。
5.2 查看端口占用:lsof 和 netstat 的实战对比
热词里有 “linux的9090端口什么再用”,这类问题本质是“查端口被谁占用”。最常见的手段是:
bash复制lsof -i:9090
输出结果里能看到占用该端口的进程 PID 和进程名。如果想看监听状态(LISTEN),可以:
bash复制lsof -i:9090 -sTCP:LISTEN
没有 lsof 命令时,很多系统自带 netstat:
bash复制netstat -tlnp | grep 9090
其中 -t 表示 tcp,-l 表示 listening,-n 表示不解析域名直接显示 IP,-p 显示进程。
我个人的习惯是:优先用 lsof -i:端口号,因为输出更直观,而且即使进程不是当前用户,也能看到 PID。查到 PID 后,再配合 ps -fp PID 或者 top 看具体是什么进程。
这个场景经常出现在服务启动失败时,提示 “Address already in use”。解决思路是:先 lsof -i:端口 找到占用进程,确认是不是自己要找的服务;如果是残留进程,kill PID 杀掉;如果不是服务的端口,换一个端口或者配置监听地址。
5.3 网络连通性排查:ping、curl、telnet 的组合用法
排查网络问题时,我一般按层级一步步来,每一层用一条命令:
ping 目标IP:检查本机到目标主机的基本网络连通性,看丢包率和延迟。telnet 目标IP 端口:测试目标端口是否开放,能通的话会进入一个空界面或者返回 banner,不通用Ctrl+]再输入quit退出。curl -v 目标URL:测试 HTTP/HTTPS 服务的响应情况,-v会输出完整的请求和响应头,排查 Web 服务很有用。
比如用户反映某个网页打不开,我会先 ping 看主机通不通,再 telnet 主机 80 看端口通不通,最后 curl -I 域名 看 HTTP 返回码。如果 ping 通但 telnet 不通,多半是防火墙或安全组拦了端口;如果 telnet 通但 curl 返回异常,问题大概率出在 Web 服务本身。
curl 里我再提一个高频参数:-I 只获取响应头,比如 curl -I https://example.com,能看到状态码、Server、Content-Type 等信息,特别适合快速判断一个网站是否正常。
6. 软件安装与日志排查:真实环境里的指令组合
6.1 软件包管理器的基本操作:apt 与 yum 对照
Linux 下安装软件,离不开包管理器。Debian/Ubuntu 系列用 apt,CentOS/RHEL 系列用 yum 或 dnf。日常工作里最常用的是这几组:
bash复制# Debian/Ubuntu
apt update # 更新软件源索引
apt install 软件包名 # 安装软件
apt remove 软件包名 # 卸载软件(不删配置)
apt purge 软件包名 # 卸载并删除配置
apt list --installed # 列出已安装的软件包
# CentOS/RHEL
yum install 软件包名
yum remove 软件包名
yum list installed
热词里 “linux安装docker”“linux安装nginx”“linux系统安装python” 都属于这类需求。安装前一定要先 update 或 update 对应的源,否则可能装到旧版本或者报“找不到软件包”。
装完软件后,怎么确认装没装上?用 which 命令名 或 软件包名 -v 看版本。比如 which python3、nginx -v、docker --version。
如果你需要安装的软件不在默认源里(比如某些较新的工具),就得先添加第三方源,或者直接用官方提供的安装脚本。但在这里我不细讲,因为不同软件差异很大,核心思路都是“先加源,再安装”。
6.2 systemctl 管理服务:启动、开机自启与状态查看
安装完 Nginx、Docker、MySQL 这类软件后,最常用的管理操作是:
bash复制systemctl start nginx # 启动服务
systemctl stop nginx # 停止服务
systemctl restart nginx # 重启服务
systemctl status nginx # 查看服务状态
systemctl enable nginx # 设置开机自启
systemctl disable nginx # 取消开机自启
排查服务故障时的基本流程:先 systemctl status 服务名 看状态,如果是 failed,再用 journalctl -u 服务名 查看服务的日志输出。比如:
bash复制journalctl -u nginx -n 50
这会显示 nginx 服务最近 50 行日志,很多启动失败的原因(端口被占用、配置文件语法错误等)都会直接暴露出来。Nginx 还提供了配置检查指令:
bash复制nginx -t
如果配置有语法错误,它会明确告诉你错误出现在哪个文件哪一行。所以改完 Nginx 配置,先 nginx -t 检查再 systemctl reload nginx,能避免很多事故。
reload 和 restart 的区别要弄清楚:reload 是平滑重载配置,服务不会中断;restart 是完整重启,会短暂断连。生产环境一般优先用 reload。
6.3 查看系统资源与日志文件:df、du、free 与日志轮转
服务器出问题时,最先看的往往是资源占用。几个命令:
bash复制df -h # 查看磁盘分区使用率
du -sh /var/log # 查看目录总大小
free -h # 查看内存使用情况
top # 实时查看 CPU、内存占用最高的进程
df -h 的 -h 表示以人类可读格式显示(GB、MB),不加会显示成字节,读起来很费劲。du -sh 则是分析某个目录占用多少空间的利器,排查“磁盘满了”时的标准操作是:
df -h看哪个分区满了。cd 到分区挂载点,用du -sh *或du -h --max-depth=1找到最占空间的目录。- 一层层深入,定位到大文件或日志目录,再做清理。
日志文件特别大时,先确认有没有被进程占用,再用 truncate -s 0 日志文件 清空而不是直接 rm,因为有些进程即使文件被删了,句柄还握着,磁盘空间不会立即释放。
7. 常见问题与排查技巧实录
7.1 文件被占用删不掉
现象:rm 文件 提示 “Device or resource busy”。原因是有进程正在使用这个文件。解决方法是先定位进程:
bash复制lsof 文件名
然后根据输出的 PID,确认后 kill PID,再删除文件。
7.2 命令明明装好了,却提示 command not found
通常是 PATH 环境变量没包含该命令所在目录。常见原因有两个:一是安装在了 /usr/local/bin 但 PATH 没配;二是刚装完软件,还没重新加载 shell 配置。执行 source ~/.bashrc 或重新登录试试。也可以用 find / -name 命令名 2>/dev/null 找到实际路径,再创建软链接到 /usr/local/bin。
7.3 权限 denied 的排查顺序
先 whoami 确认当前用户,再看目标文件的归属和权限(ls -l),再确认目录权限(ls -ld 目录),最后用 sudo 提升权限或者 chown 纠正归属。很多时候问题只是文件归属不对,不是权限不够。
7.4 磁盘明明没满,但写入报错
这种场景我遇到好几次,最后的元凶都是 inode 耗尽了。df -h 看的是空间,df -i 看的是 inode。如果 inode 用满了,即使还有剩余空间,也无法创建新文件。排查方法:
bash复制df -i
inode 满的原因通常是大量小文件(比如临时文件、图片缓存、日志碎片)堆满了目录,需要定位并清理。
7.5 修改配置文件后服务没生效
分几种情况:一是需要 reload 而不是 restart;二是改错了配置文件路径,服务实际读的是另一个文件;三是配置语法有误,服务直接启动失败。验证手段分别是:systemctl reload、nginx -t 或 ss -tlnp 看监听端口是否变化、journalctl -u 服务名 看报错日志。
7.6 网络故障排查顺序速查
| 排查目标 | 命令 | 结果判断 |
|---|---|---|
| 基础连通性 | ping -c 4 目标IP |
有回包说明网络层通 |
| 端口连通性 | telnet 目标IP 端口 |
能进入说明端口通 |
| HTTP 服务状态 | curl -I 目标URL |
看返回码是否为 200 |
| 本地端口占用 | lsof -i:端口 |
看哪个进程占用 |
| 域名解析 | nslookup 域名 |
确认域名是否解析到正确 IP |
| 本机路由 | ip route 或 route -n |
检查默认网关是否正常 |
这些命令组合起来,基本能覆盖日常 90% 的网络问题定位需求。
最后再分享一个小技巧:如果在服务器上排查问题时间比较长,建议开一个 script 记录终端输入输出,比如 script -f /tmp/debug.log,操作完再退出,这样后面复盘或者写报告时,能精准看到每条命令的输出,不用靠记忆去还原现场。我在处理一些复杂线上问题时,这个习惯帮我省了很多回溯的功夫。
