说实话,跟着教程学过 Linux 的人很多,但能真正上手干活的人很少。我见过不少同学把命令抄在笔记里背了一堆,到了真实终端前依然不知道从哪下手。命令本身不难,难的是脑袋里没有建立一套“在 Linux 下思考问题”的逻辑。这篇教程我不想给你罗列一本命令手册,而是带着你在 CentOS 7.9 环境里走一遍真实操作流程,从拿到一台新机器开始,把文件、文本、权限、进程这些最核心的东西全部过一遍,每个命令都告诉你为什么要这样用、实际输出长什么样、哪里容易踩坑。
如果你正准备考证、刚转行做运维,或者开发环境从 Windows 切到 Linux 还有点不适应,这篇内容应该能帮你省不少折腾的时间。我会用模拟终端输出的方式还原操作画面,你照着敲一遍,基本就能建立自己的手感了。
1. 动手前先弄清三件事:环境、用户、备份
1.1 为什么选 CentOS 7.9 做练习环境
很多初学者会在“学哪个发行版”这件事上纠结半天。我的建议很简单:如果你的目标是进入企业级运维或者服务端开发,CentOS 7 系列是一个绕不开的参考系。它基于 Red Hat 的源码构建,和 RHEL 高度兼容,国内大量服务器还跑着这个版本。虽然它已经进入了维护周期的尾声,但存量机器多、教程文档丰富、遇到的问题几乎都能搜到解决方案,这就是新手最好的土壤。
在环境准备上,你可以用虚拟机软件装一个 CentOS 7.9 的最小化安装版本,也可以直接在云服务商开一台按量付费的实例。我个人的偏好是本地虚拟机加快照功能,因为练习中误操作把系统搞坏了可以一键还原,这是云服务器给不了的安心感。内存分配 2GB、磁盘 20GB 就够用了,没必要贪多。
1.2 拿到一台新机器后的第一轮体检
刚登录上一台陌生的 Linux 机器,我习惯先做一套“体检”,确认自己到底在什么样的环境里工作。这一套命令花不了三十秒,但能避免很多低级错误,比如把 CentOS 当 Ubuntu 用、磁盘只剩百分之几还在跑大任务。
whoami pwd hostname uname -a uptime free -h df -hT终端里你看到的画面大概是这样:
[root@localhost ~]# whoami root [root@localhost ~]# pwd /root [root@localhost ~]# uname -a Linux localhost 3.10.0-1160.el7.x86_64 #1 SMP ... x86_64 x86_64 x86_64 GNU/Linux [root@localhost ~]# free -h total used free shared buff/cache available Mem: 1.8G 280M 1.3G 8.6M 216M 1.3G [root@localhost ~]# df -hT Filesystem Type Size Used Avail Use% Mounted on /dev/vda1 xfs 20G 2.3G 18G 12% /这一轮能读出来的信息很多:当前用户是谁、当前路径在哪、主机名是什么、内核版本是多少、系统负载高不高、内存还剩多少、根分区的文件系统类型是 xfs、用了多少空间。其中df -hT里的T会显示文件系统类型,我第一次带这个参数时才发现原来磁盘格式还有这么多讲究,这个细节在排查问题时会很有用。
1.3 建立“先查文档再动手”的习惯
很多人学命令喜欢硬记参数,我觉得这是效率最低的方式。Linux 自带的帮助系统就是最好的老师,关键是你要会用。
每个命令后面加--help,能快速看到简短的参数列表。比如你突然想不起来tar解压的完整写法了,直接在终端敲:
tar --help | head -30这里用管道符把tar的帮助信息传给head,只显示前 30 行,画面不会刷屏。而man tar会打开一份完整到令人窒息的手册,里面会详细说明每个选项的含义,甚至包括退出状态码。第一次用man的时候,很多人不知道怎么退出,记住按键盘上的q键就行。
man手册里有个特别实用的搜索技巧:进入手册页后按/键,输入关键词回车,就能定位到相关内容,继续按n键可以跳到下一个匹配项。比如你想知道tar怎么排除目录,就搜exclude,比一页页翻快得多。
2. 文件与目录:Linux 世界里最核心的操作
2.1 绝对路径和相对路径的思维转换
用过 Windows 的朋友对路径并不陌生,但 Linux 的路径体系和 Windows 有个根本区别:Windows 是按盘符分区的,C 盘、D 盘是平级关系;Linux 是一棵从/(根目录)长出来的大树,所有设备、文件都挂在这棵树上。这里没有一个叫 C 盘的东西,你插入的 U 盘、新挂载的硬盘,都会被安排到某个目录下访问。
理解了这个之后,再看两个概念就很容易了。绝对路径就是从/开始的完整路径,比如/var/log/messages,不管你当前人在哪里,写全了就能直接定位,相当于你给快递员一个完整收货地址。相对路径则是从当前目录开始算,比如你在/var目录下,想进log目录,直接写cd log就行,相当于你告诉快递员“从我家门口往东走五十米”。
在cd命令里有两个快速技巧我觉得非常实用:cd ~直接回当前用户的家目录,cd -跳回上一次所在的目录。我在配置多个配置文件时经常在/etc/nginx和项目目录之间来回切换,cd -一下就能过去,省了不少打字时间。
2.2 文件增删改查的四件套
操作文件绕不开ls、cp、mv、rm这四个命令,它们看起来简单,但细节非常多。
先看ls。裸敲ls只是列出文件名,信息量太少。我几乎只用组合参数:
ls -l # 显示权限、属主、大小、修改时间 ls -a # 显示隐藏文件 ls -lh # 以人类可读的方式显示大小 ls -lt # 按修改时间从新到旧排序 cp 的问题集中在参数上。复制单个文件直接 `cp 源 目标` 就行,但复制目录必须加 `-r`。这个 `-r` 是递归的意思,会把目录里面的所有子目录和文件都复制一份。如果你希望复制后保留原始文件的时间戳、属主、权限这些属性,用 `-p`;想完整克隆一个目录的所有属性,用 `cp -a`,运维场景里备份配置目录时我基本都用它。 mv 命令表面上是移动文件,其实重命名也是它干的活。`mv old.txt new.txt` 没有任何移动,只是把文件名改了。理解这点后你会发现文件系统里“移动”和“重命名”本质上是同一个操作,只是目标路径是否发生改变的区别。 rm 命令是四件套里最需要敬畏的一个。有一次我需要清理某个构建目录,在输入命令时多敲了一个空格,把路径写错了,结果系统开始递归删除另一个目录里的文件。还好当时那个目录里有权限保护才没有造成严重后果。事后我给自己定下一条规矩:凡是包含 `rm -rf` 的命令,执行前必须用 `ls` 确认一遍路径,并且先用 `echo` 把命令拼出来看一眼。 ### 2.3 查找文件的高中低三档武器 当你的机器上文件多了,靠 `ls` 一个个找肯定不行。这时你至少需要掌握三条查找链路的取舍。 平时找文件我最长用的是 `find`,因为它可以根据各种条件组合查询。比如你想找 `/var/log` 下最近三天内修改过的日志文件: ```bash find /var/log -type f -mtime -3-type f限定只查普通文件,-mtime -3表示修改时间在三天以内。如果想找大于 100MB 的文件,用-size +100M。find还支持直接在结果上执行命令,这个功能排错时极其好用。比如找出所有.tmp结尾的临时文件删除掉:
find /tmp -type f -name "*.tmp" -exec rm -f {} \;这条命令里的{}是占位符,代表 find 找到的每一个文件,\;是命令结束的标志。第一次看这个语法容易懵,但用一次就记住了。
locate命令比find快得多,因为它并不是真去磁盘里翻找,而是去查一个预先建好的文件索引数据库。代价是这个数据库不是实时更新的,新建的文件可能查不到,需要先执行updatedb刷新。如果你只是想确认某个文件在不在系统里,用locate体验更好;如果你要做精确的条件筛选,find更靠谱。
还有一个特别容易忽略的小工具是which,它用来查找命令本身所在的位置。比如你在终端敲nginx能启动服务,但你想知道这个可执行文件到底装在哪个目录,which nginx一下就出来了。这个在排查“为什么我的 PATH 里有两个同名命令”时非常有用。
3. 文本查看与处理:日志排查的看家本领
3.1 查看文件的正确姿势
Linux 下看文件内容有好几个工具,很多人只知道cat,这其实是不够的。cat适合看小文件,比如配置文件、脚本,几秒内能显示完的内容。一旦文件大了,cat会把整屏刷过去,你什么都看不清,这时候要用less。
less是分页查看工具,打开大日志文件时几乎不会卡顿。进去之后你可以用方向键上下翻页,按/搜索关键词,按q退出。我排查日志时基本都会先less打开,搜几个关键字定位时间点,再决定下一步看哪段。
如果是看日志文件的尾部——比如程序仍在运行,日志在源源不断追加——tail -f是标配。-f是 follow 的缩写,它会持续追踪文件新增的内容并显示在屏幕上。调试一个服务为什么起不来时,我常常开着这个窗口,另一边重新执行启动命令,日志实时滚出来,问题原因一目了然。想看文件的头部若干行,用head -n 20;但如果你只关心最近的报错,tail -n 50更合适。
3.2 grep:日志排查里出场率最高的命令
没有一个做运维的人能离开grep。它的核心功能是“按模式过滤文本”,看起来简单,但配合其他工具威力巨大。
最基本的用法是找关键词:
grep "ERROR" app.log这条命令会把app.log中含ERROR的行全部打印出来。命令常年排错的场景里,我会在grep后面加几个修饰参数:-i忽略大小写,-n显示行号,-c统计匹配行数而不是输出内容。比如你要统计某个时间段内报错出现了多少次:
grep -c "TimeoutException" service.log返回一个数字,这就是次数。想排除某些无关关键字,用-v。有一次排查访问日志,我想看所有返回码不是 200 的请求,一条命令就过滤出来了:
grep -v ' " 200 ' access.log参数-E可以开启扩展正则表达式,实现更复杂的匹配。比如查找日志里同时包含 IP 地址和 500 错误码的行,可以配合正则写在一个表达式里,效果比多个管道串联更清晰,执行效率也更高。
3.3 sed 与 awk:文本处理的左右手
grep负责找内容,但如果要把找到的内容加工、替换、提取,就要请出sed和awk。
最常用的sed操作是替换。比如有一个配置文件里把旧的域名写死了,你想批量替换成新域名:
sed -i 's/old.example.com/new.example.com/g' nginx.conf-i表示直接修改文件,s是替换命令,g表示全局替换。这里有个新手最容易犯的错误:忘了加-i,跑完命令后发现文件没有任何变化,因为sed默认只是把替换结果输出到屏幕,并不会写回文件。所以如果你只是想预览替换效果,不加-i;确定没问题了再加。
awk更偏向于“按列处理”。日志文件里每行都有自己的结构,比如空格分隔的几个字段,awk '{print $1}'就能把第一列抽出来。实际运维中我经常组合使用这几个工具,形成一条分析流水线。比如分析一个访问日志,统计哪些 IP 访问次数最多:
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head这条命令先把访问日志的第一列(IP 地址)提取出来,传给sort排序,再用uniq -c统计每个 IP 出现了多少次,最后按访问次数倒序排列,取前十个。整个过程下来,你根本不需要打开表格软件,在终端里就完成了 TOP N 的分析。这类命令初看会觉得很奇怪,管道符怎么一个接一个,但习惯了之后,你会发现这就是 Linux 最迷人的地方:小工具各司其职,用管道自由组合成强大的分析流程。
4. 权限与用户:理解 Linux 的安全模型
4.1 权限位到底怎么读
用ls -l查看文件时,输出行开头那一串-rw-r--r--看着像乱码,其实信息量很大。第一位表示文件类型:-是普通文件,d是目录,l是软链接。后面九个字符分成三组,依次是属主权限、属组权限、其他人权限。
每组三个字符分别对应读r、写w、执行x。拿-rw-r--r--来说:属主可以读写,属组只能读,其他人也只能读,没有人能执行。如果某个位置是-,就代表没有对应权限。
初学的时候会觉得这串字符不够直观,所以我更推荐用数字表示法。r等于 4,w等于 2,x等于 1,把三组权限的值分别相加,就能得到一组三位数字。比如rwxr-xr-x换算出来就是 755,rw-r--r--是 644。平时写脚本部署项目时,配置文件一般用 644(可读,只有属主可写),可执行脚本和数据目录一般用 755。
这里有一个容易忽视的知识点:目录的执行权限和文件的执行权限不是一个意思。文件的x表示可运行,目录的x表示“能否进入这个目录”。所以一个目录权限为rw-r--r--时,即使你拥有读权限能列出文件名,也不能用cd进去,必须要有x。这个细节我在第一次配置共享目录时踩过坑,花了不少时间才反应过来。
4.2 用 chmod、chown 调整权限
修改权限用的是chmod。日常场景二选一:如果是给脚本加上可执行权限,用:
chmod +x deploy.sh如果是调整一组项目的统一权限,用数字表示法更快:
chmod -R 755 /data/www-R是递归,会把指定目录下所有文件和子目录的权限一并修改。这个参数看起来方便,实际上很危险,如果误操作把一些敏感文件的权限开大了,相当于给系统留了一扇敞开的门。我自己的习惯是能不加-R就不加,确需批量调整时,先ls -l看清楚现状,再动手。
修改文件属主和属组用chown。比如把 web 目录的所有者改成运行服务的专用账号:
chown -R nginx:nginx /data/www这里的第一个nginx是属主,第二个是属组,用冒号分隔。和chmod -R一样,加了递归选项也要再三确认目录路径。权限调整后建议立刻用ls -l检查,确认结果符合预期再继续下一步。
4.3 用户与组管理的基础操作
服务器上不能只有 root 一个账号。创建用户用useradd,设置密码用passwd,给用户追加到附加组用usermod:
useradd dev01 passwd dev01 usermod -aG wheel dev01这里把dev01加进了wheel组,这个组在 CentOS 的默认配置下拥有sudo权限。这样dev01可以通过sudo临时提升权限来执行管理命令,不用直接切换到 root。
理解用户体系,还应该认识两个配置文件。/etc/passwd保存着用户的基本信息,每行一个用户,用冒号分隔字段,包括用户名、UID、家目录、登录 Shell。/etc/shadow保存的是加密后的密码和密码策略配置,这个文件权限极严,普通用户无权读取。我第一次看到/etc/passwd里那一堆系统账号时还挺惊讶的,比如bin、daemon这些,它们是系统服务运行时的身份,不需要登录,所以它们的登录 Shell 往往是/sbin/nologin。
日常服务器维护我强烈建议不要长期用 root 操作。创建普通用户,装个sudo权限,遇到需要管理员权限的命令前先想三秒,确定命令含义后再执行。少用 root 不是多此一举,而是给你自己的误操作留一条缓冲。
5. 进程与网络管理:向运维实战再进一步
5.1 看清进程的真面目
服务器上跑着什么程序、吃掉了多少资源,这些都要通过进程管理命令来观察。我最常用的是ps aux,一次能看到所有用户的所有进程。它的输出里,PID是进程号,%CPU和%MEM是资源占用百分比,COMMAND是完整的命令行。
刚才说的ps aux输出是瞬间快照。如果想持续观察系统总体的资源变化,用top。它每隔几秒刷新一次,默认按 CPU 占用率排序,屏幕上方的load average三项数值分别代表过去 1 分钟、5 分钟、15 分钟的负载情况。如果这三个数持续高于 CPU 核心数,系统就处于过载状态了。
kill 命令是用来结束进程的,但“结束”也有很多层意思。默认的kill 1234发送的是TERM信号,相当于温和地请求进程自己退出,给它机会清理临时文件和释放资源。如果这个进程死活不退,才需要用kill -9 1234发送KILL信号强制结束。KILL是操作系统直接接管终止进程,不留任何清理的机会。所以我的原则是:先礼貌地发TERM,等个几秒,确认进程还在才上-9。
顺便说一句,你可能会看到“僵尸进程”这个词。它指的是进程已经结束,但父进程还没来得及回收其退出状态,系统里挂着的一个残留条目,不占 CPU 也不占内存,只是看着吓人。一般不用管它,父进程退出后被收养的进程会负责清理。
5.2 网络排查的日常操作
网络问题占运维排障的比例很高,至少需要掌握三件事:通不通、通得慢不快、端口被谁占了。
测连通性最常用的是ping,它的原理是发 ICMP 包并等待回应,用来判断目标主机是否在线:
ping -c 4 baidu.com参数-c 4表示只发 4 个包就停。不加这个参数它会一直 ping 下去。
想知道数据包从本机到目标经过了哪些中间节点,用traceroute。不过说实话,这个命令日常查看链路质量的时候用得多,排查应用问题用得相对少。排查应用故障时,更常用的是查看端口监听状态:
ss -lntp这条命令列出所有处于监听状态的 TCP 端口,-p参数显示哪个进程占用了这个端口。报错“端口被占用”时,一条命令就能定位到真凶是哪个 PID。老教程里总让你用netstat,但新装的 CentOS 7 上未必预装,ss是它的替代者,功能更全面也更快。
防火墙也是网络排查里容易忽略的一环。CentOS 7 默认使用firewalld,临时开放端口用:
firewall-cmd --add-port=8080/tcp这个操作在系统重启后会失效,要永久生效需要加--permanent参数并重新加载:
firewall-cmd --permanent --add-port=8080/tcp firewall-cmd --reload排查“外部访问不了服务”的问题时,先确认服务本身在监听,再确认防火墙有没有放行,这两步排查完基本就能解决大半问题。
5.3 用 systemd 管理服务状态
CentOS 7 最大的改变之一就是用systemd取代了旧的 SysV init 管理体系。现在管理服务基本都是围绕systemctl命令展开。
启动、停止、重启、查看状态,四件套直接对应:
systemctl start nginx systemctl stop nginx systemctl restart nginx systemctl status nginx想让服务开机自启,执行systemctl enable nginx;不想自启了,用disable取消。enable并不等于立刻启动,它只是创建了开机启动的软链接,当前状态的启动还得靠start,两个命令分开记就不容易混淆。
排查服务为什么启动失败时,journalctl是核心工具。比如 nginx 启动失败,用:
journalctl -u nginx -n 50-u指定查看哪个服务,-n 50只看最近 50 行日志。很多启动失败都是配置语法错误,系统日志里会直接给出具体的错误行,比你自己猜快得多。
6. 排障与避坑:一些真实环境中的经典问题
6.1 磁盘明明满了,却找不到大文件
这是运维里最经典的诡异问题:df -h显示磁盘使用率 100%,但du统计出来的目录总大小却远小于磁盘容量。第一次遇到时我整个人都懵了,以为文件系统出了问题。
后来才明白过来,真相往往是有进程正在占用一个已经被删除的文件。Linux 的文件删除机制比较特殊:只要还有进程持有该文件的句柄,磁盘空间就不会真正释放。你用rm删掉了文件,但从磁盘占用角度看,删除操作只是断开了目录项,数据块还被那个进程占着。
排查方法是用lsof检查哪些文件被标记为已删除:
lsof +L1 | grep deleted找到占用文件的进程 PID 后,重启这个进程或者让它释放文件描述符,磁盘空间就会回来。这种问题在日志服务上特别容易出现,所以大日志文件在轮转前一定要确认服务有没有重新打开新的日志文件,否则旧的句柄一直占着空间。
6.2 命令找不到:PATH 与环境变量的经典问题
在终端敲了一个命令,系统却提示command not found,这种事新手遇到会慌,老手会先冷静查 PATH。echo $PATH可以查看当前系统会在哪些目录里寻找可执行文件。如果你自己编译的软件装在/usr/local/xxx/bin,但 PATH 里没包含这个目录,那无论怎么敲命令都找不到。
解决办法有两个。临时生效,直接在 shell 里改:
export PATH=$PATH:/usr/local/xxx/bin永久生效,把这一行写进/etc/profile或者当前用户家目录的.bashrc文件里,然后重新登录或执行source ~/.bashrc。注意修改系统级的 PATH 要谨慎,万一改坏了,连ls、cat这些基础命令都可能找不到。
还有一类“命令找不到”是软件压根没装。CentOS 上通过包管理器安装就行:
yum install -y net-tools装完之后再跑原来的命令,一般就能通了。
6.3 文件被占用,删不掉怎么办
有时你想删掉一个文件,系统却提示Device or resource busy。这在挂载点、进程日志文件、数据库数据文件上很常见。强制删除不是好办法,先搞清楚谁在用才是正路:
fuser -v 文件路径fuser会列出正在使用这个文件的进程。找到 PID 后,确认该进程是否还需要这个文件,如果确定不需要,就把对应进程停掉,再删文件。如果某个目录被挂载了,umount提示 busy,也可以用fuser -mv 目录路径查谁在里面,退出相关进程后再卸载。不要上来就重启服务器,很多时候重启只是掩盖了真正的问题源头。
还有一个很容易被忽略的坑:你在某个目录里执行了cd,shell 的当前工作目录还停留在这个挂载点上,同样会导致umount失败。解决方法是先cd /退出该目录,再尝试卸载。
7. 一些让我效率翻倍的使用习惯
7.1 用好 Tab 键和历史记录
我对新人的第一个建议不是学更多命令,而是用好 Tab 键。输入命令和文件名时随时按 Tab 补全,不仅能减少拼写错误,还能帮你发现自己记错的文件名。如果有多个匹配项,快速按两下 Tab,系统会把所有可能的选项列出来,省得反复ls查看。
方向键上下可以翻历史记录,这个大家基本都会。但你知道吗,history命令能列出所有执行过的命令记录,配合grep可以快速找回“上一次跑过的那条长长的命令”:
history | grep "nginx restart"还有一个极其好用的组合:按Ctrl + R进入反向搜索模式,输入几个关键字,它会自动补全你历史上的某条命令。这比从历史列表里翻找快得多。
7.2 用别名和 bashrc 定制自己的环境
如果你发现自己经常打同一串命令,就该考虑配置别名了。在.bashrc文件里加一行:
alias ll='ls -lh'重新加载后,敲ll就等于执行ls -lh,节省时间不说,还更不容易出错。我自己的机器上还配了几个常用的安全别名:
alias rm='rm -i' alias cp='cp -i' alias mv='mv -i'-i参数让这些危险操作在覆盖文件前都会问一句确认,对新手来说等于多了一道保险。等你真的熟练了再取消也不迟。
修改完.bashrc,记得用source ~/.bashrc让它立即生效,或者重新登录一次。顺便提醒一下,.bashrc是当前用户的配置,每个用户都有自己的那份,配置前先看清楚当前用户是谁。
7.3 软链接:多版本命令切换的利器
当同一个软件装了多个版本,或者某个二进制文件放在很深的路径里,软链接能帮你省掉很多麻烦。创建一个软链接的命令是:
ln -s /usr/local/python3/bin/python3 /usr/bin/python3这样/usr/bin/python3看起来就是一个文件,实际上它指向的是真实路径。之后你执行python3命令时,系统顺着链接找到了真实的可执行文件。想要切换版本时,只需要把这个软链接重新指向另一个路径即可。
需要说明的是,软链接删除不会影响原始文件,放心删。它相当于 Windows 里的快捷方式,只是 Linux 的链接在命令行下使用起来更像是原始文件本身。
最后说点实在的
其实我很想说一句:命令本身不值得你花太多时间死记硬背,真正值钱的是你面对问题时的排查思路。比如磁盘满了该往哪个方向查,启动失败去哪个日志找原因,服务被占用怎么定位进程,这些思维框架一旦建立起来,哪怕遇到完全陌生的命令,你也能借助man和--help自己搞定。
Linux 的学习曲线一开始确实有点陡,我见过太多人在cd和ls之间转了几天就放弃了。但只要你坚持每天在真实的终端里敲几十条命令,坚持把一个完整的小项目部署到 Linux 服务器上跑起来,那种“能控制一台机器”的感觉会很快抵消最初的挫败感。等命令逐渐变成肌肉记忆,你会发现自己排查问题的速度越来越快,甚至开始享受这种直接和系统底层对话的感觉。多练,多踩坑,多把出错信息读完整,这就是我给你的终极建议。