正确使用 Linux 命令行
Linux 命令行是理解 Linux 系统最直接的入口。服务器管理、软件开发、容器、云计算和自动化任务都离不开它。真正有效的学习方式不是背诵大量命令,而是理解 Linux 的文件系统、权限模型、文本流和进程模型,再用少量工具组合出清晰、可重复的工作流。
本文以常见的 Bash 环境为主,适用于 Ubuntu、Debian、Fedora、Rocky Linux、Arch Linux 等发行版。不同发行版的软件包管理器和默认配置可能不同,执行涉及系统配置的命令前,应先确认当前系统和权限范围。
示例中的
$表示普通用户提示符,#常用于表示 root 提示符。它们不是命令的一部分。除非确有必要,不要长期使用 root 账户,也不要给所有命令随意添加sudo。
1 认识 Linux 命令行环境
1.1 终端、Shell 与发行版
- 终端负责显示输入输出,例如 GNOME Terminal、Konsole、Windows Terminal;
- Shell解释命令,例如 Bash、Zsh、Fish;
- 发行版组合 Linux 内核、系统工具和软件仓库,例如 Ubuntu、Fedora;
- 命令最终通常由 Shell 内建功能、可执行文件、函数或别名提供。
先了解当前环境:
whoami
pwd
printf '%s\n' "$SHELL"
uname -a
cat /etc/os-release
/etc/os-release 通常能告诉我们发行版名称和版本。不要只凭教程页面判断系统;同一命令在不同发行版上可能使用不同参数或包名。
1.2 读懂提示符
常见提示符:
user@host:~/project$
user是当前用户;host是主机名;~/project是当前目录;$通常代表普通用户;#通常代表 root。
查看当前身份和所属组:
id
groups
hostname
1.3 判断命令来自哪里
type cd
type ls
command -v git
which git
type 能区分别名、函数、Shell 内建命令和外部程序;脚本中更推荐 command -v 判断程序是否存在。
2 学会查帮助
2.1 man、help 与 –help
man ls
man 5 passwd
ls --help
help cd
man查看系统手册,按q退出;help查看 Bash 内建命令;--help常用于外部程序的简要帮助;man 5 passwd中的5表示配置文件格式章节,而不是命令章节。
搜索手册主题:
man -k archive
apropos network
复制网络命令前,先在本机帮助中确认参数。不同版本的 GNU、BusyBox 和 BSD 工具可能存在差异。
3 Linux 文件系统与路径
3.1 常见目录
Linux 以 / 作为文件系统根目录:
| 路径 | 常见用途 |
|---|---|
/home |
普通用户的主目录 |
/root |
root 用户的主目录 |
/etc |
系统和服务配置 |
/var |
日志、缓存和持续变化的数据 |
/tmp |
临时文件,可能被自动清理 |
/usr |
用户空间程序、库和共享数据 |
/opt |
可选或第三方软件 |
/dev |
设备文件 |
/proc |
内核和进程信息的虚拟文件系统 |
Linux 路径区分大小写:README.md 和 readme.md 是两个不同文件。
3.2 查看与切换目录
pwd
ls
ls -lah
cd /var/log
cd ..
cd ~
cd -
.表示当前目录;..表示上级目录;~表示当前用户主目录;cd -返回上一次所在目录;- 以
/开头的是绝对路径,否则通常是相对路径。
操作前确认真实路径:
realpath ./target
readlink -f ./target
符号链接可能让表面路径和真实目标不同。删除或修改前,尤其要确认链接最终指向哪里。
3.3 引号、变量与通配符
name='Viraha'
printf '%s\n' '$name'
printf '%s\n' "$name"
- 单引号中的内容按字面值处理;
- 双引号允许变量和命令替换;
- 未加引号的变量可能发生分词和通配符展开。
安全习惯是:变量作为路径或参数时,默认加双引号。
file='My Notes.txt'
cat "$file"
常见通配符:
*匹配任意数量字符;?匹配一个字符;[0-9]匹配一个数字。
先用 printf 或 ls 查看展开结果,再把通配符用于移动和删除:
printf '%s\n' ./*.log
4 文件与目录操作
4.1 阅读文件
cat README.md
less README.md
head -n 20 README.md
tail -n 20 README.md
tail -f /var/log/example.log
cat适合较短文件;less适合分页阅读,按q退出;head和tail查看开头与结尾;tail -f持续跟踪新增日志,按Ctrl+C停止。
判断文件类型和编码:
file README.md
file -i README.md
4.2 创建、复制与移动
mkdir notes
mkdir -p notes/linux/commands
touch notes/todo.txt
cp notes/todo.txt notes/todo.backup.txt
cp -a notes notes-copy
mv notes/todo.txt notes/tasks.txt
cp -a 尽量保留权限、时间戳和链接等属性,适合目录备份。覆盖重要文件时,可以使用交互确认:
cp -i source.conf target.conf
mv -i old-name new-name
4.3 谨慎删除
rm -i notes/tasks.txt
rmdir empty-directory
rm 通常不会进入桌面回收站。执行递归删除前,应先:
target='./directory-to-check'
realpath "$target"
find "$target" -maxdepth 2 -print
不要把 /、~、空变量、未经确认的命令替换或宽泛通配符交给递归删除。下面的高风险形式不应在不了解后果时使用:
rm -rf ...
更稳妥的做法是先创建备份,或把目标移动到专门的待清理目录,观察一段时间后再删除。
5 查找文件与内容
5.1 find
find . -type f -name '*.md'
find . -type d -name node_modules -prune
find /var/log -type f -mtime -1 2>/dev/null
find 的条件从左到右组合。第一次编写时只使用查找和 -print,确认结果后再添加处理动作。
处理包含空格或换行的文件名时,使用空字符分隔:
find . -type f -name '*.log' -print0 |
xargs -0 -r grep -l 'ERROR'
5.2 grep 与快速搜索
grep 'error' app.log
grep -n -i 'error' app.log
grep -RIn --exclude-dir=.git 'TODO' .
若安装了 ripgrep:
rg -n 'TODO'
rg --files
Git 仓库中也可以使用:
git grep -n 'guestbook_api'
6 管道、重定向与文本处理
6.1 标准输入、输出和错误
Linux 命令通常使用三个标准流:
- 标准输入 stdin,文件描述符
0; - 标准输出 stdout,文件描述符
1; - 标准错误 stderr,文件描述符
2。
command > output.txt
command >> output.txt
command 2> error.log
command > all.log 2>&1
> 覆盖文件,>> 追加文件。重定向前确认目标,避免覆盖重要内容。
6.2 用管道组合小工具
printf '%s\n' apple banana apple |
sort |
uniq -c |
sort -nr
管道把前一个命令的标准输出交给后一个命令。Linux 工具往往专注于一件事,组合后完成复杂处理。
常见文本工具:
wc -l file.txt
cut -d: -f1 /etc/passwd
sort names.txt
uniq -c sorted-names.txt
tr '[:lower:]' '[:upper:]'
awk -F: '{print $1}' /etc/passwd
sed -n '1,20p' file.txt
修改文件前,先让 sed、awk 输出到终端或新文件,不要一开始就使用原地编辑选项。
6.3 tee
tee 可以同时显示并写入文件:
printf '%s\n' 'example' | tee output.txt
printf '%s\n' 'next line' | tee -a output.txt
需要通过 sudo 写系统文件时,sudo echo ... > file 往往无效,因为重定向由当前 Shell 执行。可以在明确确认内容后使用 sudo tee,但仍应先备份原配置。
6.4 命令连接与退出码
command_a && command_b
command_a || command_b
command_a ; command_b
printf '%s\n' "$?"
&&:前一条成功才执行后一条;||:前一条失败才执行后一条;;:无论前一条是否成功都继续;$?:最近一条命令的退出码,0通常表示成功。
脚本中应明确处理失败,而不是假设“没有输出就是成功”。
7 用户、组与权限
7.1 读懂权限位
ls -l script.sh
示例:
-rwxr-x--- 1 user developers 1200 Aug 10 10:00 script.sh
- 第一位表示类型,
-是普通文件,d是目录,l是链接; - 后面三组分别对应所有者、所属组和其他用户;
r是读取,w是写入,x是执行;- 对目录而言,
x还意味着能够进入和访问其中项目。
7.2 chmod、chown 与 umask
优先使用容易读懂的符号形式:
chmod u+x script.sh
chmod go-rwx private.txt
chmod u=rw,go= config.ini
数字形式也很常见:
chmod 644 public.txt
chmod 755 script.sh
不要为了“解决权限问题”直接使用 chmod 777。它会让所有用户获得写权限,可能引入安全风险。
修改所有者通常需要管理员权限:
sudo chown user:group path
查看默认权限掩码:
umask
umask -S
7.3 正确使用 sudo
sudo 只提升当前命令权限。执行前确认:
- 命令来源可信;
- 路径明确;
- 是否有备份;
- 是否可以先在普通目录测试;
- 是否真的需要管理员权限。
不要使用 sudo 掩盖文件所有权错误,否则可能让项目文件逐渐变成 root 所有,普通用户反而无法正常开发。
8 进程、任务与服务
8.1 查看进程
ps aux
ps -ef
pgrep -af nginx
top
如果安装了 htop,可以获得更友好的交互界面。
8.2 前台与后台任务
long-running-command &
jobs
fg %1
bg %1
Ctrl+C通常发送中断信号;Ctrl+Z暂停当前前台任务;jobs查看当前 Shell 的任务;fg、bg控制前后台。
退出终端后仍需运行的正式服务,不应只依赖 nohup。优先使用 systemd、容器编排或专门的进程管理器。
8.3 结束进程
kill PID
kill -TERM PID
kill -KILL PID
默认 TERM 允许程序清理资源并退出。KILL 无法被进程捕获,只应作为最后手段。先用 ps 或 pgrep 精确确认 PID,不要只凭模糊名称批量结束进程。
8.4 systemd 与日志
systemctl status ssh
journalctl -u ssh --since today
journalctl -p err -b
启动、停止或启用服务通常需要 sudo:
sudo systemctl restart example.service
重启前先查看状态和日志,并确认配置语法。生产服务还应考虑连接中断和回滚方案。
9 网络与远程访问
9.1 地址、端口与 DNS
ip address
ip route
ss -lntp
getent hosts viraha.online
dig viraha.online A
ping -c 4 viraha.online
ping 失败不一定表示网站不可用,因为服务器或网络可能禁止 ICMP。应继续检查 DNS、TCP 端口和 HTTP。
curl -I --max-time 20 https://viraha.online
curl -v --max-time 20 https://viraha.online
9.2 SSH
ssh user@example.com
ssh -p 2222 user@example.com
scp local.txt user@example.com:/remote/path/
rsync -av --dry-run ./local/ user@example.com:/remote/path/
第一次连接时应核对服务器指纹,不要盲目接受变化的主机密钥。使用 rsync 前先加 --dry-run 查看计划传输内容;源路径末尾是否带 / 会影响目录结构。
SSH 私钥应限制权限:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
9.3 代理变量
printf '%s\n' "$HTTP_PROXY"
printf '%s\n' "$HTTPS_PROXY"
printf '%s\n' "$NO_PROXY"
命令行成功而浏览器失败,或相反,常常是因为二者使用了不同代理。排查时记录请求经过的 DNS、代理和目标地址,不要只比较表面上的 URL。
10 软件包管理
先确认发行版,再使用对应工具。
10.1 Debian 与 Ubuntu
sudo apt update
apt search package-name
apt show package-name
sudo apt install package-name
10.2 Fedora 与 Rocky Linux
dnf search package-name
dnf info package-name
sudo dnf install package-name
10.3 Arch Linux
pacman -Ss package-name
pacman -Si package-name
sudo pacman -S package-name
不要把不同发行版的包管理命令混用。安装前确认软件包名称、来源和依赖变化;生产系统升级前应查看发行说明并准备快照或回滚方案。
11 环境变量与 Shell 配置
11.1 查看与设置变量
printenv
printf '%s\n' "$PATH"
export APP_ENV='development'
只在当前 Shell 中设置的变量,退出后通常消失。需要持久化时,可根据用途修改 ~/.bashrc、~/.profile 等文件。
11.2 安全修改 PATH
export PATH="$HOME/.local/bin:$PATH"
路径之间使用冒号分隔。不要不加检查地覆盖整个 PATH,也不要把不可信或所有人可写的目录放在前面。
修改配置后,可以重新加载:
source ~/.bashrc
重新加载前先检查语法,最好保留另一个可用终端,以免错误配置导致新 Shell 无法正常启动。
11.3 别名与函数
alias ll='ls -lah'
type ll
别名适合交互快捷操作,不适合依赖复杂参数的自动化脚本。较复杂逻辑应写成函数或独立脚本,并纳入版本控制。
12 编写可靠的 Bash 脚本
12.1 最小脚本结构
#!/usr/bin/env bash
set -euo pipefail
main() {
local target=${1:-}
if [[ -z "$target" ]]; then
printf '用法:%s TARGET\n' "$0" >&2
return 2
fi
printf '目标:%s\n' "$target"
}
main "$@"
- shebang 指定解释器;
"$@"保留所有参数边界;local限制函数变量范围;- 错误提示写入 stderr;
- 用返回码表达成功或失败。
set -euo pipefail 能帮助暴露错误,但也有边界情况。使用它之前仍要理解条件判断、管道和允许失败的命令,不应把它当作完整的错误处理方案。
12.2 始终引用变量
cp -- "$source" "$destination"
双引号防止空格和通配符展开;-- 告诉支持该约定的程序,后面的内容即使以 - 开头也按普通参数处理。
12.3 检查脚本
bash -n script.sh
shellcheck script.sh
bash -n 检查语法但不执行;ShellCheck 能发现未引用变量、错误条件和不可移植写法。真正执行前,还应在临时目录或测试环境中验证。
13 使用 Git 管理修改
git status
git diff
git diff --check
git add path/to/file
git diff --staged
git commit -m "docs: update article"
git push origin main
更新本地仓库:
git pull --ff-only origin main
明确列出暂存文件能避免把密钥、日志或无关修改提交进去。提交前应检查 git diff --staged,确认内容和范围。
不要在不理解影响时运行:
git reset --hard
git clean -fd
它们可能不可恢复地丢弃本地文件。重要工作先提交、建立分支或复制备份。
14 安全使用习惯
14.1 先读后写
可靠的顺序是:
- 用
pwd确认位置; - 用
ls -la和git status查看现状; - 用
realpath确认目标; - 使用
--dry-run、只读查询或新输出文件预览; - 执行一次修改;
- 重新检查结果和退出码;
- 保留备份和回滚路径。
14.2 不盲目执行网络脚本
下面这种模式会把网络内容直接交给 Shell:
curl URL | sh
更稳妥的做法是先下载到临时文件,阅读内容、核对来源和校验值,再在受控环境执行。即使网站可信,也要考虑域名劫持、供应链风险和脚本更新。
14.3 保护密钥
密码、API Token、SSH 私钥和云服务 Secret 不应进入:
- Git 仓库;
- 公开日志;
- 命令截图;
- Shell 历史;
- 前端代码。
可以使用专门的 Secret 管理服务、受限权限文件或交互输入。配置文件若包含敏感值,应设置合理权限并加入 .gitignore。
15 常见故障排查
15.1 command not found
command -v command-name
type command-name
printf '%s\n' "$PATH"
可能是程序未安装、名称错误、PATH 缺少目录,或当前 Shell 尚未重新加载配置。
15.2 Permission denied
先运行:
ls -ld path
namei -l path
id
检查父目录权限、文件所有者、挂载选项和执行位。不要直接用 chmod 777 或 sudo 掩盖原因。
15.3 No such file or directory
pwd
ls -la
realpath -m ./expected/path
还要检查大小写、隐藏字符、符号链接以及脚本解释器路径。脚本明明存在却无法运行时,可能是 CRLF 换行或 shebang 指向不存在的解释器。
15.4 磁盘空间不足
df -h
df -i
du -sh ./* 2>/dev/null | sort -h
df -h 看容量,df -i 看 inode。删除日志前先确认日志轮转和服务行为,不要在生产系统中随意清空文件。
15.5 服务或端口异常
ss -lntp
systemctl status example.service
journalctl -u example.service -n 100 --no-pager
按“配置—进程—监听端口—防火墙—DNS—客户端请求”的顺序排查,比反复重启服务更有效。
15.6 命令长时间无输出
可能正在等待网络、锁、标准输入或大量磁盘操作。可以:
- 阅读命令帮助,确认是否为交互模式;
- 在另一个终端查看进程和资源;
- 为网络请求设置
--max-time; - 使用
Ctrl+C请求正常中断; - 不要在状态未知时反复启动相同写操作。
16 一套可靠的 Linux 工作流
pwd
ls -la
git status
git diff
# 执行项目自己的测试或构建
git diff --check
git add path/to/file
git diff --staged
git commit -m "docs: update Linux command-line guide"
git push origin main
面对系统配置时,再增加:
- 备份原配置;
- 查询当前服务状态;
- 使用程序提供的配置检查命令;
- 只修改一个因素;
- 平滑加载或重启;
- 立即查看日志并准备回滚。
17 动手练习
在自己的主目录中创建临时练习区,不要使用系统目录:
practice="$HOME/linux-cli-practice"
mkdir -p "$practice"
cd "$practice" || exit 1
printf '%s\n' 'alpha' 'beta' 'alpha' > words.txt
cp -i words.txt words.backup.txt
sort words.txt | uniq -c
grep -n 'beta' words.txt
ls -lah
继续练习:
- 用
find找出所有.txt文件; - 用
wc -l统计行数; - 用
tar创建归档; - 查看归档内容而不解压;
- 使用明确路径移走练习目录,而不是直接递归删除。
归档示例:
tar -czf practice.tar.gz -C "$HOME" linux-cli-practice
tar -tzf practice.tar.gz
结语
Linux 命令行的力量来自统一的文件模型、清晰的权限体系和可组合的文本工具。掌握它并不意味着追求最短的命令,而是能解释每个参数、预测影响范围、验证执行结果,并在出现问题时找到证据。
最值得培养的习惯仍然是:先定位,后操作;先查看,后修改;普通权限优先;变量始终引用;危险操作必须保留恢复路径。
文章评论
欢迎围绕本文内容补充资料、分享经验或提出不同看法。请尽量保持友善并说明理由;评论经站长审核后公开。
✍️发表评论
邮箱和真实姓名不会公开;真实姓名完全选填。评论只会显示在当前文章下,并需要审核后公开。
💬本文评论