Linux 命令行是运维工程师和程序员都绕不开的基本功。只要你会使用ls、cd、grep这类命令,你就能操作服务器、排查日志、写部署脚本,也能更好地理解 Docker、Kubernetes、CI/CD 这些现代基础设施背后发生了什么。很多初学者会被命令的数量吓到,实际上 Linux 命令的体系非常规律,只要理解“命令 + 参数 + 对象”的组合方式,再掌握几组高频命令,就能覆盖日常八成以上的工作场景。
这篇教程按照从 0 到 1 的学习路径展开,先从 Shell 和终端的区别讲起,再带你在终端里完成文件操作、文本处理、权限管理、软件安装、进程管理、远程登录和脚本自动化。每条命令都会保留英文术语,比如路径 path、权限 permission、进程 process、管道 pipe,因为后续查官方文档、搜英文资料都要依赖这些词。学完以后,你可以自己打开 Linux 终端,独立完成环境检查、文件整理、权限配置、日志排查和一个简单的 Shell 脚本编写。
1. 先理解 Linux 命令行是什么:Shell、终端与命令的执行过程
很多第一次接触 Linux 的人会把“终端”“命令行”“Shell”当成同一个东西。它们确实经常一起出现,但在技术上是三个不同概念。先分清楚这三者,后面看任何教程都不会糊涂。
1.1 终端和 Shell 不是一回事
终端 terminal 是人与系统交互的窗口。在图形桌面里,你打开“终端”“Terminal”或“Konsole”,看到的是一个黑色的输入窗口;在没有图形界面的服务器上,你通过 SSH 登录后看到的提示符也属于终端。终端的主要作用是接收键盘输入,并把结果显示在屏幕上。
Shell 才是真正解释命令的程序。用户输入ls这个词,Shell 会去系统的 PATH 环境变量所指定的目录里查找名为ls的可执行文件,找到后创建子进程来执行它。常见的 Shell 有:
| Shell 名称 | 常见系统 | 特点 |
|---|---|---|
| Bash | Ubuntu、CentOS 默认 | 最常见,脚本兼容性好 |
| Zsh | macOS、部分新系统 | 自动补全更强,主题丰富 |
| Fish | 用户自行安装 | 语法高亮友好,但脚本兼容性弱 |
| Sh | 最小化系统 | 最基础的 Shell,很多脚本用它解释执行 |
所以你在终端里输入的命令,并不是终端自己处理的。终端只是把字符串交给 Shell,Shell 负责解析、查找、执行,再把标准输出 stdout 返回给终端显示。这个分工,就是理解整个命令行体系的第一步。
1.2 命令解析的完整过程
一条命令从输入到执行大致经历四个步骤:
- 终端接收输入,按回车后会传递到 Shell。
- Shell 对字符串做分词,把空格隔开的部分拆成命令名和参数。
- Shell 根据命令名搜索可执行文件。
- 找到后启动子进程执行,执行结果写到标准输出。
用一个例子说明:
ls -l /home这里ls是命令名,-l是选项 option,/home是参数 argument。Shell 会把整条字符串拆成三个部分,然后找到/bin/ls程序,把-l和/home传进去。ls程序读取/home目录的元数据,把结果按长格式打印出来。
这个机制解释了为什么很多初学者会遇到的错误叫command not found。原因通常是这个命令不在 PATH 指定的目录里。使用echo $PATH可以看到当前 Shell 会搜索哪些目录:
echo $PATH输出类似:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin如果你把可执行文件放到/opt/mybin却没有加入 PATH,那么在终端直接输入文件名称就会提示 command not found,只能输入完整路径/opt/mybin/demo来执行。
1.3 为什么要用英文记忆这些术语
编程和运维资料中,英文术语出现频率极高。ls全称是 list,含义是列出目录内容;cd全称是 change directory,含义是切换目录;pwd全称是 print working directory。记住了英文全称,你就能猜出很多命令的用途。例如mkdir是 make directory,rmdir是 remove directory,chmod是 change mode。英文单词不是额外负担,而是记忆命令的一把钥匙。
注意:不要用死记硬背的方式学习命令。先理解命令全称和设计目标,再结合终端实际输入感受输出结果,记忆效率会高很多。
2. 搭建最小学习环境:WSL、虚拟机还是真实 Linux
在学习 Linux 命令行时,环境选择直接影响学习成本。没有必要一开始就买服务器或重装系统。根据自己现有的电脑系统,选一条最顺的路线即可。
2.1 三种环境对比
| 方案 | 优点 | 缺点 | 适合人群 |
|---|---|---|---|
| Windows 上使用 WSL | 启动快,文件互访方便,支持 systemd | 与真实虚拟机隔离度稍低 | 想在 Windows 笔记本上快速入门 |
| 虚拟机 VirtualBox / VMware | 隔离完整,可模拟多种发行版 | 占用内存较大,启动慢 | 需要测试多系统或学习系统安装 |
| 云服务器或真实服务器 | 最接近生产环境,可部署服务 | 需要购买或申请资源 | 学习部署、网络、运维方向 |
| Linux 物理机 | 性能最好,体验最直接 | 需要重新装系统,有迁移成本 | 已决定长期使用 Linux 作为主力系统 |
对完全零基础的人,推荐优先使用 WSL 或虚拟机。WSL 安装快、占用小,适合先练命令;虚拟机更适合想理解系统安装过程的人。
2.2 推荐路线:WSL 安装步骤
在管理员身份的 PowerShell 中执行:
wsl --install新版命令会默认安装 Ubuntu,并且自动启用 WSL2。安装完成后重启电脑,在开始菜单找到 Ubuntu 图标打开即可。
如果你已经安装了旧版 WSL,想查看当前版本:
wsl --status安装完成后,打开 Ubuntu 终端,输入:
cat /etc/os-release如果看到类似VERSION_ID="22.04"的输出,说明系统已经就绪。
国内网络环境下,如果 Ubuntu 的软件源下载过慢,可以替换为国内镜像源。这里给出一个通用的修改思路:先备份源文件,再替换,最后更新软件包列表。
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list sudo apt update注意,不同发行版和版本的源地址结构可能不同,落地前先确认系统版本和镜像站说明。
2.3 打开终端后的第一个检查清单
进入终端后,建议先做这几个基础检查:
| 目的 | 命令 | 预期结果 |
|---|---|---|
| 查看当前用户是谁 | whoami | 输出一个用户名 |
| 查看当前所在目录 | pwd | 输出类似 /home/你的用户名 |
| 查看内核版本 | uname -r | 输出内核版本字符串 |
| 查看系统发行版 | cat /etc/os-release | 显示系统名称和版本 |
| 查看磁盘空间 | df -h | 显示挂载点和剩余空间 |
这组命令不需要刻意背。它们的作用是让你在一个新环境里快速建立“我在哪、我是谁、系统是什么状态”的判断。后续所有操作都建立在这些基础信息之上。
3. 第一组命令:定位与查看文件(pwd、ls、cd、cat、less)
判断自己是否入门,有一个简单标准:能不能在一个陌生目录里快速弄清楚自己在哪里、目录里有什么、文件内容是什么。这组命令就是解决这三个问题。
3.1 pwd:我在哪
pwd全称 print working directory,意思是打印当前工作目录。在 Shell 中运行的所有命令,默认都在一个“当前目录”中生效。输入:
pwd输出类似于:
/home/zhangsan这表明当前工作目录是/home/zhangsan。Linux 文件系统使用斜杠/作为路径分隔符,这与 Windows 的反斜杠\不同。根目录 root directory 用/表示,/home是系统存放普通用户家目录的位置。
3.2 ls:这里有什么
ls是最常用的命令之一。直接输入ls会列出当前目录下所有可见文件和目录:
ls常见变体:
| 命令 | 英文含义 | 效果 |
|---|---|---|
ls -l | long format | 长格式显示详细信息 |
ls -a | all | 显示隐藏文件,包括以点开头的文件 |
ls -lh | human readable | 显示人类可读的文件大小 |
ls -lt | sort by time | 按修改时间排序 |
ls -R | recursive | 递归显示子目录 |
3.3 ls -l 的每一项都代表什么
输入ls -l,你会看到类似这样的输出:
drwxr-xr-x 2 zhangsan zhangsan 4096 Oct 15 10:30 documents -rw-r--r-- 1 zhangsan zhangsan 120 Oct 15 10:31 notes.txt逐列拆解:
- 第一列是文件类型和权限。第一个字符
d表示目录,-表示普通文件,l表示符号链接。后面 9 个字符分成三组,分别代表所有者 owner、所属组 group、其他用户 others 对文件的读 read、写 write、执行 execute 权限。 - 第二列是硬链接数量。
- 第三列是文件所有者。
- 第四列是文件所属组。
- 第五列是文件大小,单位字节。
- 第六列是最后修改时间。
- 第七列是文件名。
这 10 个字符(如drwxr-xr-x)中的r代表读,w代表写,x代表执行,-代表没有对应权限。理解这一列之后,后续学习chmod会非常轻松。
3.4 cd:如何在目录间切换
cd全称 change directory。进入子目录:
cd documents返回上一级目录:
cd ..回到当前用户的家目录:
cd ~或者直接输入cd不加参数,也能回到用户家目录。回到家目录后,使用pwd应该看到/root或/home/用户名,取决于当前用户是谁。
特别注意相对路径 relative path和绝对路径 absolute path的区别。以/开头的是绝对路径,例如:
cd /etc/nginx不包含在最前面写/的路径是相对路径,它基于当前目录来解析。例如从/home/zhangsan执行cd documents,实际进入的是/home/zhangsan/documents。
3.5 cat、less、head、tail:查看文件内容
查看文件内容,最简单的是cat:
cat notes.txtcat会把整个文件一次性输出到屏幕。适合小文件,但大文件会刷屏。
分页查看用less:
less /var/log/syslog在less界面中按空格向下翻页,按q退出。这个命令在处理日志时必不可少。
只看文件开头若干行:
head -n 20 notes.txt只看文件末尾若干行,并实时跟踪日志变化,是运维场景里的经典用法:
tail -n 50 /var/log/syslog tail -f /var/log/syslogtail -f中的-f代表 follow,也就是持续跟随文件末尾新增内容。调试服务、观察日志时,这个命令几乎每天都在用。
注意:不要在大日志文件上直接使用
cat。应该用tail看尾部、grep过滤关键字、less分页浏览。
4. 文件操作:创建、复制、移动、删除
文件操作是 Linux 日常使用的核心。在运维工作中,你经常需要创建目录、备份配置、移动日志、清理过期文件。
4.1 创建目录和文件:mkdir、touch
创建目录:
mkdir project mkdir -p project/src/main/java-p全称 parents,含义是如果父目录不存在,则一并创建。没有-p时,如果父目录缺失,命令会报错。
创建空文件:
touch empty.txttouch的核心作用是更新时间戳。如果文件不存在,它会创建空文件;如果文件已经存在,它会把文件的修改时间更新为当前时间。
4.2 复制与移动:cp、mv
复制文件:
cp notes.txt notes_backup.txt复制目录时,需要加-r参数,表示递归复制:
cp -r project project_backup移动文件或重命名文件:
mv notes.txt /home/zhangsan/documents/ mv oldname.txt newname.txtmv既不要求加-r,对文件和目录都通用。它本质上是把文件从一个路径移动到另一个路径,如果目标路径是一个已经存在的文件名,则相当于重命名。
4.3 删除命令 rm 的高风险场景
删除文件:
rm temp.txt删除目录及内部所有内容:
rm -rf oldproject-r表示递归,-f表示强制,不询问确认。rm -rf是运维场景中危险系数最高的命令之一。它会静默删除,不进入回收站,一旦执行,普通情况下无法恢复。
生产环境中的建议:
- 不要在根目录或其他关键目录下随意执行
rm -rf。 - 删除前先用
ls -l或find确认目标和路径。 - 重要数据一定要有备份。
4.4 把文件移动到回收站的安全做法
原生rm没有回收站概念。为了让删除操作可恢复,很多 Linux 用户会安装trash-cli工具。它提供trash-put、trash-list、trash-restore等命令,把删除行为改成“移动到回收站”。
在 Ubuntu/Debian 上安装:
sudo apt install trash-cli使用:
trash-put oldfile.txt trash-list trash-restoretrash-restore会列出回收站里的文件,让你选择恢复哪一个。这种做法更适合有心理负担的删除操作,例如清理旧配置、删除暂时不用的项目目录。
但在生产服务器上,推荐做法仍然是:先压缩备份,再删除,或者直接保留日志滚动策略。回收站只适合个人电脑和实验环境,不适合作为生产环境的删除策略。
5. 搜索与文本处理:grep、find、sed、awk、xargs
命令行之所以高效,不只是因为能操作文件,还因为可以通过一条命令在大量日志、配置、代码中完成搜索和统计。在编程和运维工作中,掌握文本处理命令的意义甚至超过掌握图形界面工具。
5.1 grep 按内容搜索
grep按文件内容搜索,这是排查日志最重要的命令。基础用法:
grep "ERROR" application.log常用参数:
| 参数 | 含义 | 示例 |
|---|---|---|
-i | 忽略大小写 | grep -i error application.log |
-r | 递归搜索目录 | grep -r "error" /var/log/ |
-n | 显示行号 | grep -n "error" application.log |
-v | 反向匹配,输出不含关键字的行 | grep -v "debug" application.log |
-c | 只统计匹配次数 | grep -c "error" application.log |
使用场景示例:
grep -n "OutOfMemoryError" /var/log/backend/error.log这条命令会在日志中定位 OOM 错误,并显示具体行号和行内容。找到行号之后,再用sed或less提取上下文。
5.2 find 按条件搜索文件
grep搜索内容,find搜索文件名、类型、时间、大小。常用示例:
find /etc -name "*.conf" find /var/log -type f -mtime -7 find /home -type d -name "node_modules"解释:
-name按文件名匹配,支持通配符*。-type f表示普通文件,-type d表示目录。-mtime -7表示最近 7 天内修改过。
如果只知道文件内容中的某个特征,可以使用:
grep -rl "database password" /etc-l只输出文件名,而不是输出匹配到的行内容。找到包含关键字的文件列表,这种组合是排查配置问题的高频操作。
5.3 管道与重定向是命令行组合的基石
管道 pipe 用|表示,它把前一条命令的输出作为后一条命令的输入。这是 Linux 命令行最核心的组合思想。
ls -l /usr/bin | head -n 10这条命令先列出/usr/bin的全部文件,再把输出交给head,只显示前 10 行。
重定向 redirect 用>和>>表示。>会把内容写入文件,如果文件存在则覆盖;>>表示追加。示例:
echo "hello" > test.txt echo "world" >> test.txt cat test.txt标准输出和错误输出也可以重定向:
command > output.log 2>&12>&1的意思是把标准错误 stderr 重定向到标准输出 stdout 指向的地方,让错误信息和正常输出写入同一个文件。排查启动日志时,这行命令非常常用,不然错误信息可能在终端里一闪而过。
5.4 sed 做替换,awk 做列处理
sed是流编辑器 stream editor,适合对文本做替换、删除、打印。最常用的替换语法:
sed 's/old/new/g' file.txt示例:
sed 's/ERROR/WARN/g' application.log > converted.log这个命令把文件中的所有ERROR替换成WARN,输出到新文件。g表示全局替换,不加g只替换每行第一次出现的位置。
awk更适合按列处理。要查看当前目录下所有子目录的名称,可以解析ls -l输出中的第一列和最后一列:
ls -l | awk '{print $1, $9}'$1表示第一列,$9表示第九列。常见用法是按冒号或逗号切分字段:
awk -F: '{print $1}' /etc/passwd-F:表示以冒号作为分隔符,然后打印第一列,也就是用户名列。这个命令在查看系统用户时很常用。
5.5 被低估的 xargs:把前一条输出变成参数
xargs的作用是把标准输入转换成命令行参数。这里先看一个常见痛点。
删除/tmp下所有.log文件,你可能会写:
find /tmp -name "*.log" | rm但这条命令是错的。管道把文件名传递给rm的标准输入,而rm并不从标准输入读取参数,它只接收命令行参数。正确写法需要用到xargs:
find /tmp -name "*.log" | xargs rmxargs把前一条命令输出的每一行内容,作为rm的命令行参数追加到后面,最终等价于:
rm /tmp/a.log /tmp/b.log /tmp/c.log批量压缩文件:
find . -name "*.log" | xargs tar -czf logs.tar.gz批量查看文件大小:
find . -type f | xargs ls -l要特别注意,如果文件名中含有空格,直接使用xargs可能出错。可以用-0配合find -print0来处理:
find . -name "*.log" -print0 | xargs -0 rm-print0让 find 输出文件名时用空字符分隔,而不是换行符;xargs -0也按空字符读取。这样带空格的文件名也能正确处理。
注意:
xargs是把输入变成参数,不是把输入变成“待处理的数据流”。理解了这个区别,你就能判断什么时候用xargs,什么时候直接使用管道。
6. 权限与用户:从报错 permission denied 开始理解
初学 Linux 时,Permission denied是常见报错。它的含义是当前用户对某个文件或目录没有足够的操作权限。理解这个报错,需要理解 Linux 的权限模型。
6.1 Linux 权限模型:rwx
每个文件或目录都有一组权限标记。三组权限分别作用于:
- 所有者 user owner
- 所属组 group
- 其他用户 others
每组权限由读 read、写 write、执行 execute 组成。对于文件:
r表示可以读取文件内容。w表示可以修改文件内容。x表示可以把它当作程序执行。
对于目录:
r表示可以列出目录中的文件名。w表示可以在目录中创建、删除、重命名文件。x表示可以进入这个目录。
所以一个目录如果只有r没有x,你能看到文件名,但无法进入目录。
6.2 chmod 和 chown 的使用
修改权限用chmod,全称 change mode。数字表示法很常用:
| 权限组合 | 英文 | 数值 |
|---|---|---|
r | read | 4 |
w | write | 2 |
x | execute | 1 |
所有者权限、组权限、其他用户权限各自相加,得到一个三位数。比如755表示所有者有rwx7,组和其他用户有r-x5。
chmod 755 script.sh chmod 644 notes.txt修改文件所有者用chown,全称 change owner:
sudo chown zhangsan:zhangsan notes.txt这条命令把文件所有者改成zhangsan,所属组也改成zhangsan。冒号前是用户名,冒号后是组名。
6.3 新建用户与用户组管理
在运维场景中,不应长期使用 root 用户操作服务器,而应该创建普通用户,并在需要时使用sudo提权。
新建用户:
sudo useradd -m -s /bin/bash devuser其中-m表示创建用户家目录,-s指定默认 Shell。
实际使用中,更建议使用adduser,它是交互式工具,会让你设置密码:
sudo adduser devuser将用户加入 sudo 组:
sudo usermod -aG sudo devuser在 CentOS/RHEL 系列系统中,sudo 组名通常是wheel:
sudo usermod -aG wheel devuser切换到该用户:
su - devuser6.4 sudo 的正确使用
sudo的含义是 superuser do,即以另一个用户身份执行命令,默认是 root。当普通用户执行:
sudo apt update系统会要求输入当前用户的密码。密码验证通过后,命令以 root 权限执行。
生产环境建议:
- 不要用 root 日常登录。
- 给不同运维人员分配独立账户,并加入相应组。
- 执行高风险命令前先确认当前用户和路径。
- 涉及密码、密钥的操作要先确认目标环境是否属于生产环境。
7. 运维视角:软件安装、进程、网络、远程登录
命令行不只是操作文件,它还承担软件安装、服务管理、网络排查和远程登录等运维工作。
7.1 软件包管理:apt 与 yum
不同 Linux 发行版使用不同的包管理器。Debian/Ubuntu 系列使用apt,CentOS/RHEL 系列使用yum或dnf。
Ubuntu 上更新软件包列表和升级软件:
sudo apt update sudo apt upgrade安装软件:
sudo apt install nginx卸载软件:
sudo apt remove nginxCentOS 系列:
sudo yum install nginx sudo yum remove nginx安装 Docker 是运维的常见操作。Ubuntu 上如果使用官方源,需要先安装依赖并配置 Docker 的仓库。更快速的方式是安装 docker.io 包:
sudo apt install docker.io sudo systemctl enable docker sudo systemctl start docker安装完成后查看版本:
docker --version注意:这里只是便于本地实验的安装方式。生产环境安装 Docker 建议参考 Docker 官方文档,配置仓库、确认版本、设置运行时和存储驱动,并且根据企业镜像源进行调整。
7.2 查看和结束进程:ps、top、kill
查看当前系统进程:
ps -ef-e表示显示所有进程,-f表示完整格式。常见组合是配合grep过滤:
ps -ef | grep java查看进程的实时资源占用,使用top:
top在top界面里按q退出。新版系统也可以使用htop,但默认可能没有安装。
根据 PID 结束进程:
kill 12345如果普通kill不生效,可能需要强制结束:
kill -9 12345kill -9会直接向进程发送 SIGKILL 信号,进程无法捕获和处理,会立即终止。在业务系统中,不到万不得已不要使用-9,因为可能会导致数据未落盘或状态不完整。应先尝试正常终止,再等待一段时间,确认无效后再强制结束。
7.3 网络排查:ping、ss、netstat
检查网络连通性:
ping -c 4 baidu.com-c 4表示只发送 4 个 ICMP 数据包。
查看端口监听状态:
ss -tlnp参数含义是:-t显示 TCP,-l显示监听状态,-n直接显示数字端口,-p显示进程信息。如果要看更传统风格的输出,也可以使用:
netstat -tlnp排查端口被占用:
ss -tlnp | grep 8080这条命令会输出监听 8080 端口的进程和 PID,是排查端口冲突最直接的方法。
7.4 远程管理:ssh 与 scp
SSH 是远程登录 Linux 服务器的标准方式。
登录服务器:
ssh zhangsan@192.168.1.10如果 SSH 端口不是默认的 22:
ssh -p 2222 zhangsan@192.168.1.10复制文件到远程服务器:
scp ./backup.tar.gz zhangsan@192.168.1.10:/home/zhangsan/从远程服务器下载文件:
scp zhangsan@192.168.1.10:/var/log/nginx/error.log ./scp基于 SSH 协议,传输过程是加密的。日常管理多个服务器时,建议配置 SSH 密钥认证,避免反复输入密码。
推荐做一次密钥登录配置:
ssh-keygen -t ed25519 ssh-copy-id zhangsan@192.168.1.10ssh-keygen会生成一对密钥,私钥 id_ed25519 保留在本机,公钥 id_ed25519.pub 通过ssh-copy-id传送到服务器。之后 ssh 登录会优先使用密钥认证,不再需要输入密码。
8. 从命令到脚本:用 Shell 自动化重复操作
命令行熟练之后,很多工作是重复的,比如每天备份日志、批量修改文件名、定时检查磁盘空间。把这些操作写进 Shell 脚本,可以让机器自动执行。
8.1 第一个脚本:变量与 echo
创建一个脚本文件:
vim hello.sh输入内容:
#!/bin/bash name="world" echo "hello, $name"脚本第一行#!/bin/bash称为 shebang,它告诉系统这个脚本用哪个解释器来执行。echo用于输出内容,$name是变量引用。
给脚本添加执行权限:
chmod +x hello.sh执行脚本:
./hello.sh8.2 条件判断与循环
Shell 脚本支持条件判断。判断文件是否存在:
if [ -f "/etc/nginx/nginx.conf" ]; then echo "nginx config exists" else echo "nginx config not found" fi循环批量处理文件:
for file in /tmp/*.log; do echo "processing $file" gzip "$file" done这段脚本会把/tmp下所有.log文件先打印信息,再压缩成.gz。注意变量外面加了双引号,避免文件名中有空格时出错。
8.3 一个可复用的日志备份脚本
这个脚本适用于日常备份:把日志目录打包,按日期命名,保留最近 7 天备份,删除更早的压缩包。
#!/bin/bash backup_dir="/var/log/myapp" dest_dir="/backup/logs" today=$(date +%Y%m%d) archive_name="myapp-$today.tar.gz" mkdir -p "$dest_dir" tar -czf "$dest_dir/$archive_name" -C "$backup_dir" . find "$dest_dir" -name "*.tar.gz" -type f -mtime +7 -delete echo "backup done: $dest_dir/$archive_name"关键点:
$(date +%Y%m%d)会生成类似20250601的日期字符串。tar -czf创建 gzip 压缩包。find ... -mtime +7 -delete删除 7 天前的备份文件。
脚本保存为backup_logs.sh,添加执行权限后即可运行。
8.4 脚本执行方式与常见错误
执行脚本有几种方式:
./backup_logs.sh bash backup_logs.sh sh backup_logs.sh如果直接执行./backup_logs.sh报Permission denied,说明缺少执行权限,用chmod +x修复。如果脚本中用到sudo,执行时也会要求输入密码。
一个典型错误是行尾使用 Windows 换行符\r。这通常发生在 Windows 文本编辑器编辑脚本后传到 Linux 的情况,会报错$'\r': command not found。可以使用sed去掉回车符:
sed -i 's/\r$//' backup_logs.sh脚本最好在 Linux 环境里编写和编辑,或者在 Windows 编辑器里确保保存为 LF 换行。
注意:刚写好的脚本不要直接投放到生产环境。先在测试目录里用非关键数据跑一遍,核对压缩包内容、日志输出和删除结果,再加到定时任务中。
9. 命令行排查路径:从现象倒推原因
碰到命令行报错时,先不要慌。按“输入是否正确、路径是否存在、权限是否允许、依赖是否安装、资源是否足够”这个顺序排查,大多数问题都能定位。
9.1 命令找不到 command not found
现象:
docker: command not found排查步骤:
- 确认命令是否已安装:
which docker。 - 如果没有输出,说明命令不在 PATH 中,或者软件未安装。
- 确认软件包是否安装:
dpkg -l | grep docker。 - 安装后重新初始化:在 Ubuntu 上执行
sudo apt install docker.io。 - 如果命令已存在但不在 PATH 中,使用完整路径执行,或将目录加入 PATH。
| 检查项 | 命令 | 结果 |
|---|---|---|
| 命令所在位置 | which docker | 有路径则已安装 |
| 软件包状态 | dpkg -l | 显示已安装版本 |
| PATH 内容 | echo $PATH | 查看包含的目录 |
9.2 Permission denied 权限拒绝
现象:
./deploy.sh -bash: ./deploy.sh: Permission denied可能原因:
- 文件没有执行权限。
- 文件系统挂载时使用了 noexec 选项。
解决方案:
chmod +x ./deploy.sh如果权限确认无误但仍然报错,检查挂载选项:
mount | grep /data如果输出中包含noexec,需要修改挂载参数,或者把脚本复制到其他目录执行。
9.3 端口被占用 port already in use
现象:
Failed to bind to 0.0.0.0:8080排查步骤:
- 查看 8080 端口占用情况:
ss -tlnp | grep 8080。 - 找到 PID 和进程名。
- 确认该进程是否还需要运行。
- 结束不需要的进程:
kill PID,或修改当前应用的监听端口。
一个常见坑是旧版本服务进程没有退出,导致新服务启动失败。这时先看 PID 对应的启动时间和命令行参数,确认后再结束进程。
9.4 磁盘写满 No space left on device
现象:
No space left on device即使df -h显示还有空间,也可能出现这个报错,原因是 inode 耗尽。检查方式:
df -h df -idf -h显示磁盘容量使用情况,df -i显示 inode 使用情况。如果 inode 使用率达到 100%,说明存在大量小文件,常见于临时目录或日志目录。
清理方式:
find /tmp -type f -mtime +3 -delete或者查找占用大量 inode 的目录:
find /var/spool -type f | wc -l9.5 命令行排错速查表
| 问题现象 | 常见原因 | 检查命令 | 处理建议 |
|---|---|---|---|
| command not found | 未安装或 PATH 缺失 | which 命令名 | 安装软件或补充 PATH |
| Permission denied | 权限不足 | ls -l 文件名 | chmod 或改用 sudo |
| port already in use | 端口被占用 | ss -tlnp | grep 端口 | 结束旧进程或换端口 |
| No space left | 分区或 inode 已满 | df -h、df -i | 清理大文件或小文件 |
| 配置修改后不生效 | 未重启服务或改错文件 | nginx -t等命令 | 验证配置后重启服务 |
| 中文显示乱码 | 字符集不匹配 | locale、echo $LANG | 设置 LANG 或使用 UTF-8 |
10. 编程与运维场景下的最佳实践与扩展方向
命令行入门之后,最重要的是养成使用习惯,并逐步向脚本化、自动化、云原生方向扩展。
10.1 命令行使用的五个习惯
- 先确认当前目录再执行操作。删除、覆盖、移动文件之前,用
pwd和ls -l确认路径。 - 重要操作先备份。批量修改或删除之前,先压缩一份存档。
- 多命令组合时先小范围验证。把管道命令里的前面部分单独执行,确认输出结果符合预期,再拼接完整链路。
- 使用历史记录。方向键上下翻历史命令,使用
history查看过去的输入,避免重复敲长命令。 - 写完脚本立即做权限收敛。脚本默认不要有
-rwxrwxrwx权限,按需设置用户和组。
10.2 运维与编程如何利用命令行
对运维方向的人来说,要继续掌握 systemd 服务管理、日志分析、监控告警、网络抓包和故障演练。对编程方向的人来说,命令行是构建、测试、部署的基础。你写一段 Java、Python 或 Go 代码,最终都要进入编译、运行、查看日志的循环,这个循环基本都在 Linux 命令行上完成。
建议练习场景:
| 场景 | 命令组合 |
|---|---|
| 查看 Java 应用日志中最近的异常 | tail -n 200 app.log | grep -n "Exception" |
| 统计访问日志中某个接口的请求次数 | grep "/api/order" access.log | wc -l |
| 找出占用磁盘最大的目录 | du -sh * | sort -hr | head |
| 批量重命名文件 | for f in *.txt; do mv "$f" "${f%.txt}.bak"; done |
| 检查远程服务器端口是否能连接 | nc -zv 192.168.1.10 22 |
du -sh *配合sort -hr和head,可以看到当前目录下占用空间最大的几个项目,是磁盘排查中高频使用的一条组合命令。
10.3 下一步学习路线
命令行入门之后,建议按顺序扩展以下方向:
- 文本处理进阶:继续练习
awk、sed、grep的组合,能读懂日志分析脚本。 - Shell 脚本语言:学习变量、条件、循环、函数、退出码,能写出可复用的运维脚本。
- 服务管理:掌握 systemd 的 service 文件写法与服务管理命令。
- 网络与远程管理:理解 ssh、scp、rsync、防火墙和端口转发。
- 自动化工具:学习 Ansible 或类似工具,把重复的手工操作变成可重复执行的 playbook。
- 容器化:在 Linux 上安装 Docker,理解镜像、容器、数据卷和网络模型。
阅读英文资料时,优先熟悉这些词汇:terminal、shell、command、option、argument、permission、process、service、port、log、script、cron。这些词会在所有 Linux 官方文档和开源项目说明中反复出现。
命令行不是一天学完的,但只要掌握了目录导航、文件操作、文本处理、权限管理、脚本编写这条主线,你就已经超过了“只会敲几个命令”的阶段。后续遇到具体问题时,再按需查询命令手册help和man,比如:
ls --help man ls--help适合快速查看常用参数,man是完整手册,阅读时需要耐心一点。这两条命令是你在命令行世界里持续学习的入口。