刚摸到 Linux 的时候,很多人第一反应都是:这和 Windows 不太一样。确实,Linux 系统环境不是靠一个“桌面”就能概括的,它更像是一套把硬件、内核、文件系统、用户权限和命令行工具全部串起来的组合。你日常工作里接触最多的就是那些 Linux 命令,不管你是做运维、嵌入式开发,还是只打算在自己笔记本上装个 Linux 当主力机,把系统环境里的几个核心机制先想清楚,后面的操作会顺手很多。这篇文章是我这些年实际使用 Linux 的经验整理,覆盖从文件操作、用户权限到软件安装、网络排查的常见命令,也会把那些容易踩的坑一并指出来。适合刚入门的人,也能给有一定基础但没系统梳理过的人做个参考。
1. 先把“Linux 系统环境”这个概念掰开揉碎
很多人装好 Linux 后打开终端,第一句就会问:我该敲什么?其实,在背命令之前,你先得知道自己面对的到底是一套什么东西。Linux 环境不是一个单一软件,它由好几层组成,每一层都决定了你后续命令能不能正常跑起来。
1.1 发行版、桌面环境、终端各自扮演什么角色
Linux 这个词严格说指的是内核,但普通用户日常用的是“发行版”。发行版 = 内核 + 软件包管理器 + 预设的桌面环境 + 一堆默认工具。不同发行版之间最大的差别不是内核版本,而是包管理器:Debian/Ubuntu 系用 apt,Red Hat/CentOS/Fedora 系用 yum 或 dnf,Arch 系用 pacman。所以你看教程的时候一定要先看对方写的发行版,别把 apt install 的命令硬搬到 CentOS 上,否则连软件源都过不去。
桌面环境是另一层。GNOME、KDE、XFCE 这些只是壳,你真正要在服务器上打交道的是终端(Terminal)。终端上跑的是一层 Shell,最常见的是 Bash,也有 Zsh、Fish。Shell 本身是一个解释器,你敲的每一个命令,其实都是它启动一个子进程去执行的。理解这一点很重要:为什么有时候你在命令行改了环境变量,关掉终端再开又没了?因为那是临时变量,只作用于当前 Shell 进程,不会写进配置文件。
1.2 shell 和 PATH 才是环境的真正核心
如果说 Linux 环境里有一个东西需要优先搞懂,那一定是 PATH 变量。你可以把 PATH 理解成“命令的检索目录”。当你敲 ls 的时候,Shell 会按 PATH 里列出的目录一个个去找有没有叫 ls 的可执行文件,找到了就执行,一个都找不到就提示 command not found。
我自己刚用 Linux 时遇到过一个问题:明明装好了某个软件,敲它名字却提示找不到。后来才发现,bin 目录没加进 PATH。解决办法很简单:
bash复制export PATH=$PATH:/opt/mytool/bin
这个命令的作用是把 /opt/mytool/bin 追加到现有 PATH 后面。注意,前面必须先写 $PATH,等于把旧路径保留下来,否则会覆盖掉系统原有路径,连 ls 都用不了。想让这个改动永久生效,就把它写到 ~/.bashrc,然后执行 source ~/.bashrc。
看 PATH 当前值、确认一个命令的真实位置,是非常实用的习惯:
bash复制echo $PATH
type -a python3
which docker
type -a 这个命令可以显示一个名字对应的所有解释,比 which 更清楚,比如它会告诉你某个命令是内置命令还是外部程序。which 只能查外部程序,查 Shell 内置命令时什么都查不到。
1.3 输入法等“桌面细节”也要提前配好
在服务器上你可能不需要输入法,但如果你在自己电脑上装 Linux 当日常系统用,中文输入法是绕不开的坑。Linux 下常见方案是 fcitx5 或 ibus,安装后要设置环境变量,让图形程序能加载输入法框架。以 fcitx5 为例,装好后要在 ~/.xprofile 或 ~/.bashrc 里加:
bash复制export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
很多国产桌面发行版,比如 Deepin 或 UOS,已经把这些东西都集成好了,开箱即用。如果你用的是这些系统,桌面软件兼容性问题会少很多,适合不想折腾的人。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 文件目录操作:最常用,也最容易出事
文件操作是 Linux 命令里出现频率最高的一块,也是初学者相对容易出事的一块。危险主要来自于两点:一是命令执行太快,没有回收站可以反悔;二是通配符和参数顺序搞错,删了不该删的东西。
2.1 基础命令怎么用更高效
基础的 ls、cd、pwd 大家都会,但很多人用得不到位。我推荐几个高频组合:
bash复制ls -lhtr
-l 看详细信息,-h 把文件大小显示成 K/M/G,-t 按时间排序,-r 倒序排列。这样最新修改的文件正好显示在最下面,配合 tail 使用非常顺手。
cd 回退目录有两个容易记混的写法:
bash复制cd .. # 回到上一级目录
cd - # 回到上一个所在目录
在多个目录之间来回切换的时候,cd - 几乎是效率神器,不用一次次输入长路径。
2.2 删除文件夹前必须想清楚的事
删除文件夹的命令是:
bash复制rm -rf 目录名
-r 表示递归删除目录内所有文件和子目录,-f 表示强制删除,不逐个确认。这个命令用得最多,也最危险,因为系统不会提醒你。以前我清理磁盘时想删某个临时目录,结果因为正在另一个目录下手误敲错了路径,等于把一堆没备份的资料删了。
有一个很容易犯的错误是把路径写反。rm -rf /tmp/log/ 和 rm -rf /tmp/log 看起来差不多,后者如果末尾漏了 /,加上前面路径有个变量为空,结果就完全不一样了。更严格的写法是:
bash复制rm -rf -- /tmp/log
-- 后面的内容会被当成路径解析,即使路径以 - 开头也不会被误认成参数。另外,删除前先执行 ls -la /tmp/log 看一眼目录内容,比什么都管用。
如果你实在担心误删,可以用一个技巧:先执行 mv 把目录移动到一个临时目录,比如 mv /tmp/log /tmp/log_$(date +%F),确认没问题后再删。等于给系统加了一个“确认期”。
2.3 cp、mv 的细节:路径、覆盖、保留属性
复制和移动命令,我见过的问题主要出在“目标路径是否以斜杠结尾”上。比如:
bash复制cp -r src/ /tmp/dest/
如果 /tmp/dest 目录不存在,系统会把 src 重命名为 dest;如果存在,则复制成 /tmp/dest/src。这个行为困惑过很多人,我建议每次复制前先用 ls -d /tmp/dest 确认目录是否存在。
跨机器或跨磁盘复制大目录时,建议加 -a 参数保留权限和时间戳:
bash复制cp -a /home/test /backup/test
-a 等价于 -dR --preserve=all,对源文件的属主、权限、时间都做保留。这点在做备份时特别重要,否则复制出来的文件时间戳全部变成了当前时间,后续查找增量文件时会被误导。
mv 也有个容易忽略的点:它只能在同一个文件系统内移动时是瞬间完成的。如果跨文件系统(比如从 / 移动到 /home),mv 底层会变成“复制+删除”,大文件时会明显卡顿。这时候用 rsync 更可控,后面讲网络命令时会详细说。
3. 从新建用户到权限管理:系统环境里最关键的安全边界
很多 Linux 新手习惯直接用 root 用户干活,一是不安全,二是容易因为权限问题把系统搞乱。一个规范的系统环境,一定会有普通用户、有 sudo 权限的用户、系统服务专用用户这几类角色。
3.1 useradd 和 adduser 的区别
Linux 下新建用户的命令看似简单,其实有两个不同的工具。useradd 是底层命令,参数很多;adduser 在 Debian/Ubuntu 系里是一个 Perl 脚本,会交互式地帮你创建主目录、设置密码、填用户信息,对新手更友好。用法如下:
bash复制sudo useradd -m -s /bin/bash zhangsan
sudo passwd zhangsan
-m 表示创建主目录 /home/zhangsan,-s 指定登录 Shell。如果不加 -m,用户登录后可能没有可用的主目录,很多软件会报权限错误。用 adduser 则直接一条命令:
bash复制sudo adduser zhangsan
它会依次询问密码等信息,全部完成后再手动设置 sudo 权限。
3.2 sudo 权限和 /etc/sudoers 的正确写法
新用户默认没有 sudo 权限。正确做法是把用户加入 sudo 组:
bash复制sudo usermod -aG sudo zhangsan
这里 -a 表示追加组,必须和 -G 一起用,否则会把这个用户移出原来的附加组。更精细的做法是直接编辑 /etc/sudoers 文件,但千万别直接用文本编辑器打开,应该用 visudo 命令,它会在保存前帮你检查语法,防止你写坏文件后 sudo 全部失效。
授权某用户不用密码执行 sudo,是这个文件里常见的配置:
code复制zhangsan ALL=(ALL) NOPASSWD: ALL
格式是“用户 主机=(可切换身份) 命令”,这里的 ALL 代表所有命令。如果只允许某用户执行指定命令,就写成:
code复制zhangsan ALL=(ALL) /usr/bin/systemctl, /usr/bin/apt
这样更符合最小权限原则,不过日常单机使用,直接给 sudo 组权限就够了。
3.3 权限位、所有者、特殊权限
文件权限是 Linux 环境里最经典的内容。-rw-r--r-- 这类输出,第一位是文件类型,后面每三位一组,分别对应 owner、group、others 的读(r=4)、写(w=2)、执行(x=1)权限。用数字表示时,chmod 755 等于 owner 可读写执行,group 和 others 可读可执行。
常用的几个权限操作:
bash复制chmod 600 ~/.ssh/id_rsa
chown user:group /data
chmod +x script.sh
有一类问题容易被忽略:对目录来说,r 权限决定你能不能列出目录内容,w 权限决定你能不能新建或删除文件,x 权限决定你能不能进入目录。所以如果目录权限是 rw-,你可以 ls 看列表,但不能 cd 进去,也不能访问里面的文件。很多 nginx 报 403 权限错误,其实不是配置问题,而是 nginx 用户对目录没有 x 权限进入。
特殊权限里我比较常用的是 setuid,比如 /usr/bin/passwd 文件,普通用户也能通过它改密码,就是因为你有 setuid 位。一般自己部署环境时很少需要手动设置,但排查权限问题时看到 rws 权限位时你至少得知道它是什么意思。
4. 远程环境必备:telnet、scp、ssh 一整套
搞 Linux 的人不可能永远坐在本机前面,远程操作才是常态。这里面的核心命令是 ssh、scp/rsync,外加排查网络连通性的 telnet 和 curl。
4.1 telnet 的适用边界和基本用法
很多人把 telnet 当成老古董,其实它在日常排障中非常有用:专门用来测试一个端口通不通。虽然它本身没有加密,不能作为正式远程登录协议,但作为端口探测工具,比 ping 有说服力得多。
用法很简单:
bash复制telnet 192.168.1.100 3306
如果端口通,屏幕会显示连接成功,或者进入一个空窗口;如果端口不通,会卡在那里直到超时,返回 Connection refused 或者 Connection timed out。判断完就可以按 Ctrl+] 进入 telnet 命令行,输入 quit 退出。这个习惯我一直保持到现在:任何服务起不来,先 telnet 一下本机端口,就能区分是服务没监听,还是防火墙拦截。
不过 telnet 只能测 TCP 端口,测不了 UDP。要测 DNS 的 UDP 53 端口,得用 nc -u -v 主机 53 这种方式。这也是一个常用组合:
bash复制nc -zv -w 3 192.168.1.100 22
-z 表示扫描模式不发送数据,-v 显示详细信息,-w 是超时秒数。
4.2 scp/rsync 传输文件的实操习惯
远程传文件最常用的是 scp,基本逻辑和 cp 类似,只是路径里要带主机名。比如:
bash复制scp /tmp/backup.tar.gz user@192.168.1.10:/data/
scp -r /opt/project user@192.168.1.10:/home/user/
-r 用于复制目录。但 scp 的缺点是断点续传和高差错同步做得不好,传大目录时最好用 rsync:
bash复制rsync -avz --progress /opt/project/ user@192.168.1.10:/data/project/
-a 保留权限和时间,-v 显示详细输出,-z 传输时压缩,--progress 显示进度。rsync 如果中断了,重新执行一遍相同的命令,它会自动跳过已经传好的部分,非常省事。注意源路径末尾带 / 和不带的差别:带 / 表示把目录内的内容复制过去,不带表示连目录本身一起复制。
4.3 端口和连通性的排查命令组合
远程连不上时,有一个固定的排查思路。先 ping 看主机通不通,再 telnet 主机 端口 看目标端口通不通,然后 ssh -vvv 主机 看认证过程卡在哪一步。这套链路走下来,问题基本就定位了。
要查看本机监听了哪些端口,用 ss 或 netstat:
bash复制ss -tlnp
netstat -tlnp
-t 只看 TCP,-l 只看监听状态,-n 显示 IP 和端口而不是服务名,-p 显示对应的进程。在 SSH 调试场景下,ssh -vvv 会打印详细日志,能直观看到是认证失败、密钥不匹配还是网络不通。绝大多数远程连接问题,用这三个命令都够用了。
5. 装软件和跑服务:从包管理器到 Docker
Linux 上装软件,绝不能像在 Windows 那样到处搜安装包,一个发行版指定的包管理器能帮你解决依赖和版本问题。这套体系理解透了,后面所有服务部署都顺了。
5.1 包管理器的常见用法
Debian/Ubuntu 系列比较常见,核心命令是:
bash复制sudo apt update
sudo apt install -y nginx
sudo apt remove nginx
sudo apt purge nginx
update 是更新软件源索引,install 才是安装软件,purge 会连同配置文件一起删。Red Hat 系用 dnf,行为逻辑类似:
bash复制sudo dnf install -y nginx
sudo dnf remove nginx
安装软件后,服务能不能起来,和包管理器本身关系很大。理论上包管理器装完 nginx 会自动注册为系统服务,但有些软件故意不自动启动。此时要用 systemctl:
bash复制sudo systemctl enable --now nginx
sudo systemctl status nginx
sudo systemctl restart nginx
enable --now 的含义是设置开机自启并立即启动。只会 apt install 不会 systemctl,等于装完一个软件却不知道怎么让它运行。
5.2 Docker 与 containerd 常用命令
现在部署环境,Docker 基本是默认出场。安装方式很简单,可以直接用官方脚本,也可以从发行版仓库装:
bash复制sudo apt install -y docker.io
sudo systemctl enable --now docker
sudo docker version
Docker 常用命令就这么几条:
bash复制docker pull nginx:alpine
docker run -d --name web -p 8080:80 nginx:alpine
docker ps
docker logs -f web
docker exec -it web /bin/bash
docker stop web && docker rm web
注意 docker run 每次指定 --name 时,镜像会创建一个新的容器,容器名不能重复。如果只是临时用,跑完就删,建议加 --rm 参数。再一个常见坑是权限:普通用户执行 docker 命令会报 permission denied,需要把用户加入 docker 组:
bash复制sudo usermod -aG docker $USER
改完之后重新登录才生效。containerd 是比 Docker 更底层的容器运行时。如果你装了纯 containerd,会用到 ctr、crictl、nerdctl 三个命令行工具。其中 nerdctl 是 containerd 的兼容 Docker 命令工具,日常使用和 docker 命令几乎一致:
bash复制nerdctl ps
nerdctl run -d --name web -p 8080:80 nginx:alpine
我在生产环境里发现,ctr 命令没有 namespace 概念,你得加 -n k8s.io 才能看到 kubernetes 管理的镜像,刚上手时容易看漏。
5.3 装机实例:Nginx、Python、FFmpeg、Ollama
举几个我自己反复装过的例子。
Nginx 装好后,默认站点在 /var/www/html,配置文件在 /etc/nginx/sites-available/ 和 /etc/nginx/sites-enabled/。改完配置先测试语法再重载:
bash复制sudo nginx -t
sudo systemctl reload nginx
Python 环境我强烈建议用虚拟环境,不要直接把包装进系统库里,否则写代码和系统升级都会打架:
bash复制sudo apt install -y python3 python3-venv python3-pip
python3 -m venv /opt/myenv
source /opt/myenv/bin/activate
pip install requests
FFmpeg 处理视频音频非常常见:
bash复制sudo apt install -y ffmpeg
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac output.mp4
如果嫌系统仓库里的 ffmpeg 版本太旧,可以下载静态编译版本解压后直接用,它不依赖系统库,解压目录放到 PATH 里就行。
Ollama 的安装现在也很简单,执行官方脚本即可,它默认监听本机 11434 端口。模型下载速度不理想时,可以配置镜像加速环境变量,原理就是让模型文件从国内可访问的镜像地址拉取,下载速度会好很多。个人电脑上跑大模型,这个工具已经成了标配。
6. 排查、补课与面试:这些命令帮你拉开差距
到了这个阶段,基础命令已经会用了,但真正体现水平的是排查问题的思路。很多 Linux 面试题其实不是考你背了多少命令,而是看你能不能用一套组合拳快速定位问题。这也是我平时带新人时最关注的能力。
6.1 find、grep、history 组合排查
find 是查找文件的工具,但很多人只会用 find / -name "*.log",慢而且结果太多。我常用的几个进阶写法:
bash复制find /var/log -name "*.log" -mtime +7 -exec ls -lh {} \;
find /data -type f -size +500M
find /data -type f -name "*.tmp" -delete
-mtime +7 表示修改时间超过 7 天的文件,-exec 可以在找到结果后执行命令,{} 代表当前文件名,末尾的 \; 是必须的语法。注意,这条命令里 -delete 很危险,建议先用不带 -delete 的命令确认列表再执行。
在文件内容里搜东西用 grep:
bash复制grep -r "error" /var/log/nginx/
grep -i "failed" /var/log/auth.log | tail -20
-r 递归搜索目录,-i 忽略大小写。配合 find 使用效果更好,比如列出所有大日志文件后再逐个 grep,就不会在几万个文件里慢慢搜。
排查和排障时,历史命令也很有用。history 命令会显示之前执行过的命令,但我一般会做两件事:一是重跑某条命令,用 !900,其中 900 是历史命令编号;二是搜历史命令,直接按 Ctrl+r,然后输入关键词,再按 Ctrl+r 继续往上翻。这个操作比翻历史输出快得多。如果要排查用户执行过哪些危险命令,可以看 /root/.bash_history 或其他用户的 ~/.bash_history。需要注意的是,历史记录在用户退出终端时才写盘,所以想强制立刻写入就执行 history -w。
6.2 日志、进程、资源占用快速定位
服务出问题时,我习惯先看日志和进程两个维度。查看日志最常用的是 journalctl:
bash复制journalctl -u nginx --since "30 minutes ago"
journalctl -u docker -f
-u 指定服务,-f 实时跟踪输出。旧一点的系统上,日志在 /var/log/,服务日志可能是 nginx/error.log、syslog 等,先用 ls /var/log/ 看看文件布局。
进程和资源占用,常用的命令是:
bash复制ps aux | head
ps aux --sort=-%mem | head -5
top -b -n 1 | head -20
htop
ps 查进程状态,top 看实时资源,htop 界面更友好。定位高 CPU 或高内存进程后,一般用 top -Hp PID 看具体线程,再用 strace -p PID 跟踪系统调用。strace 是排查问题的利器,但输出量很大,建议先加 -f 和 -e trace=network 之类的过滤参数。
磁盘满了也很常见。用 df -h 看挂载点使用率,再用 du -sh * 一层层找到占用最大的目录。生产环境里经常出现日志文件被删除但进程还占着句柄的情况,用 lsof | grep deleted 能看到这些文件,确认后重启对应进程即可释放。
6.3 面试题背后考察的 Linux 功底
我参与过不少 Linux 岗位的面试,有一点感受特别深:面试官通常不是在考单个命令,而是考你的“环境意识”。比如问 rm -rf / 为什么危险,它真正想让你说的是文件系统挂载关系、进程占用和权限边界;问 nohup 和 & 的区别,是考你对进程生命周期和终端会话的理解;问网络不通时怎么排查,是考你能不能沿着“链路层-网络层-传输层-应用层”的顺序逐个排除。
所以我的建议是,不要百条命令挨个背。你可以把命令按照场景分组:文件与目录、权限与用户、网络与远程、服务与进程、日志与排障。每个场景里找出 20% 的高频命令,把它们彻底用熟。比如嵌入式 Linux 开发的同学,可能更需要熟悉交叉编译环境、tar 打包解包和串口调试工具;做运维的同学,则要把 systemctl、journalctl、网络诊断命令练到条件反射。场景不同,重点命令也不同,但底层思路是一样的:环境是分层的,命令是服务的,你在哪一层出了问题,就用对应层级的命令去验证。
我在把 Linux 当日常工作环境用了一段时间后最大的感受是:命令本身不复杂,复杂的是你得知道命令背后依赖了哪些环境条件。文件权限对不对、PATH 里有没有路径、服务有没有启动、端口有没有被占用,这些问题在终端里都有痕迹,只是需要你用对命令去问它。遇到报错先别急着到处复制别人的命令,试着拆分一下报错信息里的关键词,比如 denied、refused、not found、no such file,再用对应的工具去查。这个习惯养成了,Linux 基本就算真正上手了。
