我清楚记得第一次学 Linux 的那天晚上,虚拟机里装好了 Ubuntu,打开终端后屏幕上只有一个孤零零的光标,脑袋里已经搜刮不出第二条命令,连ls都敲成了sl,还被旁边的人笑了好一阵。后来做了几年 Linux 运维和开发,回头看那一步,其实不是难,而是没人把“目录、命令、权限”这三件事串起来讲。这篇《linux基础》就是按这个思路来的:不追着几千条命令背,而是把 Linux 操作系统最核心的骨架拆开,再配上这些年高频率用到的 linux 常用命令、linux 文件与目录、linux 新建用户、linux 进程间通信、linux 系统安装这些实操场景,适合刚接触 Linux 的读者、准备转运维的工程师,以及想在笔记本上快速搭一套开发环境又不知从哪下手的同学。读完你至少能分清发行版是怎么回事,登录服务器后敢敲命令,知道软件要怎么装、服务要怎么管、出了问题上哪查。
1. 先搞明白:Linux 到底是什么,为什么入门总卡在第一关
1.1 内核与发行版,别再混为一谈
很多教程上来就让你装 CentOS 或 Ubuntu,结果你连自己装的是什么都不清楚。严格说,Linux 只是一个内核:它负责调度 CPU、管理内存、驱动硬件、处理网络协议栈。你平时敲的ls、grep、bash,其实来自 GNU 工具集;桌面环境、软件商店、包管理器,又是另外一层。把这些东西打包在一起,配上安装程序和默认配置,才是我们常说的“发行版”。
热搜里总能看到“linux国产”“生态最好的linux系统”“linux镜像”,也是这个逻辑。国内团队维护的发行版,比如统信 UOS、Deepin、openEuler,大多基于 Debian/Ubuntu 或 RHEL 体系,你在这个体系里学的命令,换到那些系统上基本通用。生态好不好,本质不是内核差异,而是软件包仓库里有多少东西、社区活跃度如何、硬件厂商是否适配。
选发行版我的建议很直接,不用纠结:
| 使用场景 | 推荐发行版 | 理由 |
|---|---|---|
| 个人学习、桌面开发 | Ubuntu / Deepin | 资料多,遇到问题一搜就有答案 |
| 服务器生产环境 | Rocky Linux / AlmaLinux / Ubuntu LTS | 生命周期长,稳定性优先 |
| 安全测试与渗透学习 | Kali Linux | 预装大量安全工具 |
| 嵌入式开发板 | Buildroot / Yocto / Debian | 可裁剪、可定制,适合 ARM 场景 |
别再问“哪个 Linux 最好”,先确认你的场景是桌面、服务器还是嵌入式,再选系统。
1.2 虚拟机、WSL 还是物理机:三种安装路线怎么选
linux 系统安装的姿势,直接决定你前三个小时的体验。我的建议是:新手优先用虚拟机,比如 VirtualBox 或 VMware Workstation Player,镜像从官方站点下载,安装时选“自动安装”,内存分 2~4GB,磁盘 20GB 起步。虚拟机的好处是随便折腾,快照一恢复等于没发生。
有人装虚拟机时遇到蓝屏,这是常见坑。多半是 Windows 的 Hyper-V、内存完整性或设备安全性里的内核隔离在占用虚拟化能力。解决思路三步:进 BIOS 打开 VT-x/AMD-V;在 Windows 功能里关闭 Hyper-V;在“Windows 安全中心-设备安全性-内核隔离”里关掉内存完整性。不是每台机器都全中,但按这个顺序排查基本能解决。
如果你只是想在 Windows 上跑 Linux 开发工具,WSL 也够用。热词里的“wsl needs updating your version...”提示,是 WSL 组件太旧,管理员 PowerShell 里执行wsl --update,再把默认版本设成 WSL 2 就行。但要注意,WSL 的文件系统和真正的服务器有差异,systemd、网络配置行为都不太一样,想学运维或模拟生产环境,还是老老实实装虚拟机或物理机。
物理机安装更适合准备长期把这台机器当 Linux 用的同学。下载镜像后,Windows 下用 Rufus、Linux 下用dd写 U 盘,开机引导进安装界面。这里提醒一句:U 盘写入前先备份数据,dd if=xxx.iso of=/dev/sdX bs=4M status=progress这种命令不认盘符名字,认错盘会把整个磁盘冲掉。
2. 目录与文件:从 pwd 到权限位,把“一切皆文件”吃透
2.1 必背目录结构,以及天天在用的文件命令
Linux 长期使用者的舒适感,一半来自对目录结构的肌肉记忆。不需要死记,但下面这些目录你必须知道是干嘛的:/根目录;/etc放配置文件;/home是普通用户家目录;/root是管理员家目录;/var放日志和可变数据;/tmp临时文件;/usr程序文件和系统工具;/opt第三方软件;/proc和/sys不是真实磁盘,而是内核暴露的运行信息。
linux 文件与目录操作里,有一组命令是真正的高频。我整理成速查表,建议直接贴到终端旁边:
| 需求 | 命令 |
|---|---|
| 当前位置 | pwd |
| 切换目录 | cd /etc |
| 列出文件 | ls -lh |
| 查看文件 | cat/less |
| 实时跟踪 | tail -f /var/log/syslog |
| 复制 | cp -a |
| 移动/重命名 | mv |
| 创建目录 | mkdir -p a/b/c |
| 查找文件 | find /etc -name "*.conf" |
| 搜索文本 | grep -rn "error" /var/log |
新手最容易困惑的是相对路径和绝对路径。绝对路径从根/开始,任何环境都好认;相对路径依赖你当前所在的目录,好处是短。我平时写脚本喜欢“进到脚本所在目录再干活”:
cd "$(dirname "$0")"这句话在自动化任务里几乎每篇脚本都会出现,作用就是不管谁调用这个脚本,先回到脚本自己的目录,避免相对路径找不到文件。
2.2 权限位 rwx 到底在表达什么
ls -l输出第一列像drwxr-xr-x,这十个字符是理解 Linux 权限的入口。第一个字符表示类型,d是目录,-是普通文件,l是软链接。后面九个字符分成三组,每组三个:属主权限、属组权限、其他用户权限。r读、w写、x执行。目录上的x比较特殊,它表示“是否能进入这个目录”,只有r没有x时你只能列出文件名却进不去。
修改权限用chmod,最常用的是数字法:rwx对应 4、2、1,权限值就是相加。chmod 755 file表示属主可读写执行,其他人可读可执行。普通文件默认权限通常由umask控制,比如umask 022会让新文件变成 644,新目录变成 755。改属主用chown,比如把文件交给应用用户:
sudo chown -R nginx:nginx /var/www/html理解权限后,很多“奇怪”现象就有答案了:明明文件能看到却无法修改,多半是属主或权限位没对上;脚本执行报 Permission denied,先chmod +x;目录删不掉,可能是里面有文件属于其他用户,或者目录没有写权限。
3. 用户、组与提权:sudo 不是万能钥匙,但密码过期是
3.1 新建用户不再手忙脚乱
我刚工作时还习惯直接拿 root 跑服务,后来被教训过一次才醒悟:生产环境一定要用普通用户运行业务,root 只在需要系统级操作时通过sudo临时提权。linux 新建用户的完整套路如下:
# 新增用户并指定家目录和 shell sudo useradd -m -s /bin/bash zhangsan # 设置初始密码 sudo passwd zhangsan # 加入 sudo 组(Debian/Ubuntu 是 sudo,RHEL/Rocky 是 wheel) sudo usermod -aG sudo zhangsan # 切换到新用户验证 su - zhangsanuseradd不加-m不会自动创建家目录,很多新手跑完 useradd,切过去发现没有/home/zhangsan,就是这个原因。用户信息存在/etc/passwd,密码哈希存在/etc/shadow,用户组信息在/etc/group。记住这三个文件,面试题里问“Linux 用户管理涉及哪些文件”就能脱口而出。
3.2 密码过期提醒:比你想的更需要自动化
热搜里“linux密码过期提醒通知”是运维的真实需求。系统默认密码可能长期不过期,但安全基线要求 90 天更换一次,就得主动设置:
# 查看用户密码到期信息 sudo chage -l zhangsan # 设置 90 天后过期,过期前 7 天提醒 sudo chage -M 90 -W 7 zhangsan问题是,chage 只改策略,用户登录时才会看到提醒。想主动通知,就需要写个小脚本扫描/etc/shadow。shadow 里密码段有 9 个冒号分隔的字段,我常用awk提取最后修改日期和过期天数,然后和当前日期做差,小于阈值就发告警。这个方法不复杂,但很管用,适合放到 cron 里每天执行。
顺带说一句,很多系统默认策略里密码复杂度是靠 PAM 模块pam_pwquality控制的。如果想让用户密码必须包含大小写和特殊字符,编辑/etc/security/pwquality.conf,设置minlen = 12、minclass = 4这类参数,不用额外装别的软件。
3.3 提权不是随便给的
linux 提权这个词,在安全圈和运维圈含义完全不同。运维这边,sudo配置是最常见的提权手段。用visudo编辑/etc/sudoers,给用户指定可执行的命令,是“最小权限”的正确打开方式:
zhangsan ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/less /var/log/nginx/error.log这样 zhangsan 只能重启 nginx 和查看日志,不能随便删系统文件。NOPASSWD虽然方便,但生产环境我基本不用,除非是 CI 机器这种完全可信的场景。
从安全防御角度看,普通服务器被入侵后,最常见的路径就是利用漏洞或错误配置从普通用户提权到 root。内核漏洞、SUID 文件、sudo 版本漏洞常被利用。基础防护建议三条:不要用 root 跑日常服务;定期dnf update/apt upgrade;用sudo apt update和sudo apt upgrade前先看清楚会升级什么包,重要系统建议先备份或做快照。
4. 进程与系统管理:从 ps 到 systemd 的服务化思维
4.1 查看进程、终止进程,以及“单步运行”调试
服务器卡了,第一件事不是重启,而是看进程。ps和top是最基础的两个命令。ps aux可以看清所有用户进程、CPU、内存、启动时间;top是动态刷新版,按P按 CPU 排序,按M按内存排序。要更直观可以装htop,交互体验好很多。
终止进程用kill,但别一上来就kill -9。正常流程是先kill PID,发送 SIGTERM 让进程自己清理资源退出;它不响应再用kill -9 PID。直接-9可能导致配置文件没写完、临时文件残留,数据库这类服务更是危险。
热词里“linux单步运行程序”,通常指调试。程序崩溃找不到原因,可以编译时加-g然后用gdb跑:
gdb ./myapp (gdb) break main (gdb) run (gdb) next如果是 shell 脚本,更实用的是bash -x script.sh,它会一行一行打印执行过程,变量展开后的实际值一目了然。我排查脚本问题时,bash -n检查语法、bash -x跟踪执行,两步基本能定位 90% 的问题。
4.2 进程间通信:管道、信号与 socket 的最小理解
linux 进程间通信(IPC)内容很多,但基础阶段你只需要了解几个最常用的形式。最容易看到的是管道,ps aux | grep nginx就是把前一个命令的输出当作后一个命令的输入。grep、awk、sed与管道组合起来,几乎是命令行最核心的生产力。
信号也是 IPC 的一种。kill本质是发送信号,kill -HUP常用于让 nginx 重载配置,Ctrl+C发送的是 SIGINT。真正理解“信号”,再看服务重启脚本就不会觉得玄学。
更重量级的 IPC 是 socket、共享内存和消息队列,常用于跨进程传递大量数据。做 Web 服务的人每天都在和 socket 打交道:Nginx 监听80端口,应用服务器监听127.0.0.1:9000,进程间通过 TCP 或 Unix Domain Socket 通信。一个直观例子是查看某个服务监听在哪个端口:
ss -tlnp | grep nginx没有ss的旧系统用netstat -tlnp,现在新系统基本默认装的是ss。
4.3 systemd:把服务变成“开机自动跑”
现在主流发行版都用 systemd 管理服务。它的命令风格很简单:
# 启动/停止/重启 sudo systemctl start nginx sudo systemctl enable nginx # 开机自启 sudo systemctl status nginx写一个服务的单元文件也不难,比如我们有个 Python 脚本要作为后台服务运行。新建/etc/systemd/system/myapp.service:
[Unit] Description=my python app After=network.target [Service] User=myapp ExecStart=/usr/bin/python3 /opt/myapp/main.py Restart=always [Install] WantedBy=multi-user.target保存后sudo systemctl daemon-reload,再sudo systemctl enable --now myapp。日志统一走journalctl -u myapp -f,不用自己写 log 循环。
了解 systemd 后,很多“命令不存在”的坑也能解释:为什么/etc/init.d里明明有脚本却service start失败?因为新系统里 service 命令只是 systemd 的兼容层,真正的行为还看 systemd 单元定义。学习方法很简单:装一个 nginx,然后一遍遍enable、disable、reload、status,试完你就记住了。
5. 软件安装与网络配置:从包管理器到网卡文件的修行
5.1 apt、dnf 与镜像源,装 Docker 和 MySQL 的正确姿势
Linux 装软件和 Windows 最大的区别,是用包管理器从仓库拉取。Debian/Ubuntu 系用apt,RHEL/Rocky 系用dnf(旧版yum)。基础操作如下:
# Debian/Ubuntu sudo apt update sudo apt install -y docker.io mysql-server # Rocky/RHEL sudo dnf install -y epel-release sudo dnf install -y docker-ce mysql-server“linux镜像”这个热词,不只是 ISO 镜像,还包括软件源镜像。默认源在国外,国内机器跑apt update很慢,建议改成国内镜像源。Ubuntu 改源方式:编辑/etc/apt/sources.list,把archive.ubuntu.com替换成mirrors.aliyun.com或mirrors.tuna.tsinghua.edu.cn,然后apt update。Rocky 则是修改/etc/yum.repos.d/下的 repo 文件,把mirrorlist注释掉,baseurl里的域名换成mirrors.aliyun.com/rockylinux。
装 Docker 时注意,官方源里的包有多个变体。生产环境我更建议安装docker-ce而不是docker.io,因为它维护更积极。装完别忘记把当前用户加入 docker 组,否则每次都要 sudo:
sudo usermod -aG docker $USER newgrp dockerMySQL 装完后,第一步是sudo systemctl enable --now mysql,然后sudo mysql_secure_installation清理匿名用户和测试库,最后用mysql -u root -p进入验证。别看网上一堆复杂调优参数,基础阶段把数据目录、日志、权限搞清楚,比背参数重要得多。
5.2 配置 IP、网卡文件与 SSH 远程登录
服务器装完,下一步是让它能连上网络。临时改 IP 用ip命令,但重启就失效;要持久化必须改配置文件或网络管理器。不同发行版的配置方式差异很大,这是新手最容易懵的地方。
Ubuntu 新版用 Netplan,配置文件在/etc/netplan/,常见写法:
network: ethernets: ens33: dhcp4: no addresses: - 192.168.1.100/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: [223.5.5.5] version: 2改完执行sudo netplan apply。
Rocky 的网卡文件在/etc/NetworkManager/system-connections/,也可以用nmcli操作。实用命令:
nmcli con show nmcli con mod ens33 ipv4.addresses 192.168.1.100/24 ipv4.gateway 192.168.1.1 nmcli con up ens33热词里“rocky linux网卡文件”,十有八九是在问为什么手写了ifcfg-ens33不生效。原因很简单:NetworkManager 管理状态下,手工编辑配置文件要nmcli con reload并且确认文件名的 uuid 没有被重复,直接用nmcli改更省事。
远程登录主要是 SSH。基础检查三条:确认sshd服务在跑;防火墙放行 22 端口;密钥登录比密码安全得多。
ssh-keygen -t ed25519 ssh-copy-id user@192.168.1.100之后登录就不需要输密码了。再配合/etc/ssh/sshd_config里把PasswordAuthentication改成no,安全性提升一大截。改完记得sudo systemctl restart sshd。
5.3 环境变量、Anaconda 与开发环境的常见套路
热词里“linux设置anaconda环境变量”是真实高频问题。Anaconda 安装时如果选了“仅当前用户”,安装程序会提示把一段初始化代码写进~/.bashrc。正常情况下用:
source ~/anaconda3/bin/activate conda init bash source ~/.bashrc就能让conda命令全局可用。如果还不行,手动在~/.bashrc末尾加:
export PATH="$HOME/anaconda3/bin:$PATH"然后source ~/.bashrc。看懂PATH是理解环境变量的关键:它只不过是一串冒号分隔的目录列表,shell 找命令时就按这个顺序搜索。所以脚本报“command not found”时,先echo $PATH看你的命令目录在不在里面。
很多 Linux 版开发软件,比如热词里的 workbuddy linux 客户端、modelsim linux 版、vivado linux 版本,下载下来一般是.deb包或.tar.gz压缩包。.deb用sudo dpkg -i安装;.tar.gz解压后直接看目录里的install.sh或run脚本:
tar -xzf xxx.tar.gz cd xxx ./install.sh如果提示缺库,常见做法是ldd看看动态库缺失,然后通过apt或dnf安装对应依赖。像 Wails 这种 Go 桌面框架在 Linux 上编译还缺 GTK、WebKit 库,几个apt install libgtk-3-dev libwebkit2gtk-4.1-dev就解决了。这些坑都是环境问题,不是代码问题。
6. 这些年在 Linux 上踩过的坑与排查习惯
6.1 四个高频坑,以及我的修复方案
第一个坑就是前面的虚拟机蓝屏。除了开启虚拟化,还要注意 Windows 更新后 Hyper-V 可能重新启用,表现为 VMware 提示“VMX 不可用”。解决:管理员 PowerShell 执行bcdedit /set hypervisorlaunchtype off,重启;不用时改回 auto。
第二个坑是中文输入法。Linux 默认没有 iME,热词“linux chinese ime”指向 fcitx5。安装:
sudo apt install fcitx5 fcitx5-chinese-addons然后在/etc/environment或~/.pam_environment设置GTK_IM_MODULE=fcitx、QT_IM_MODULE=fcitx、XMODIFIERS=@im=fcitx。重启会话后,Ctrl+Space 切换中英文。桌面环境不同设置位置略有差异,但万变不离这三行变量。
第三个坑是跑别人的脚本报“command not found”,但命令明明存在。常见原因有二:脚本没有#!/bin/bash头,或执行环境 PATH 不完整。把脚本第一行写成#!/bin/bash,调用的外部命令尽量写绝对路径,比如/usr/bin/systemctl,能少很多怪事。
第四个坑是网卡名称变了。以前是eth0,现在是ens33、enp0s3,导致旧教程配网卡时找不到接口。用ip addr看当前接口名,按实际名称配置;别死记eth0。
6.2 我排查 Linux 问题的固定套路
我一直相信,Linux 出问题不可怕,可怕的是瞎猜。我的排查顺序基本固定:先看服务状态,比如systemctl status nginx;再看日志,tail -f /var/log/nginx/error.log或journalctl -u nginx -xe;然后看资源,free -h、df -h、ss -tlnp。这一步能过滤掉绝大多数问题。
如果日志没给出直接答案,我会拉出退出码。执行完一条命令后,echo $?,0 表示成功,非 0 是失败,不同程序会把具体错误映射成不同码,再结合程序文档判断。比如 MySQL 客户端退出码 1,通常就是权限或 SQL 语法问题。
最后才会动用strace这类跟踪命令。strace -f -e openat ./myapp能看到程序启动时打开了哪些文件、找不到哪些库或配置,是排查“明明代码没问题但起不来”的杀手锏。不过不要一开始就上,先看日志。
6.3 一点个人体会:命令背不完,但思路可以打通
这些年陆陆续续有人让我推荐 Linux 学习路径,我的答案一直没变:先装一个 Ubuntu 虚拟机,把用户、权限、目录、进程、网络、软件安装这六块练熟,然后逼自己去回答“服务为什么起不来”这类问题。真正的提升,不是因为我背下了几百条命令,而是我知道每类问题该去哪查、用什么工具缩小范围。
日常用的最多的反而是最简单的ls、cd、grep、tail、systemctl。你不需要成为“背命令大赛冠军”,但一定要敢敲、敢看日志、敢动手实验。虚拟机里随便折腾,快照就是后悔药。把这篇的基础内容能实际操作一遍,再去碰 Docker、Kubernetes、嵌入式 Linux 或运维自动化,你会发现很多事情比想象中顺。