简介:这是一份面向Linux零基础初学者的系统性入门教程,聚焦操作系统核心概念与终端实操能力培养,帮助读者快速建立对Linux的认知框架并掌握日常运维必备技能。资源为单文件PDF文档(915KB),内容结构完整、讲解精炼,涵盖Linux与GNU关系辨析、四种安装方式对比、常用命令(mkdir/cd/ls等)详解、标准目录结构(/home、/etc、/bin等)功能说明、inode与链接机制、磁盘挂载流程、用户组与权限管理(chmod/chown)、bash/shell基础、grep/find/tee等文本处理工具、makefile构建逻辑,以及ssh、samba、gcc等关键服务与开发工具原理。内容预览显示其从Unix家族演化史切入,深入浅出梳理Linux诞生背景与技术脉络,兼具理论深度与实践导向。目前已有4413人学习下载,是适合自学、备课或教学参考的精品总结型资料。
1. 这不是一本“PDF教材”,而是一份能让你在3天内从双击图标切换到敲命令行的Linux实操切口
你手头这份《Linux操作系统基础教程.pdf》,表面看是某高校多年前的课堂教案,但真正用过的人会发现:它根本不是按“教科书逻辑”编排的——没有空泛定义,不堆砌历史年份,所有知识点都锚定在真实安装现场、真实终端操作、真实权限报错上。我拿它带过三届嵌入式方向的本科生,最常听到的反馈是:“原来ls -l第一列那串drwxr-xr-x不是密码,是能立刻改、立刻生效的权限开关”;“/mnt/cdrom不是个路径示例,是我在Red Hat 9.0光盘启动后第一个手动mount成功的挂载点”。它覆盖的不是“Linux是什么”,而是“你在服务器机房、在开发板串口、在远程VPS里必须亲手敲出来的前50条命令”。适合谁?刚配好虚拟机却卡在“怎么进终端”的新手;想转嵌入式但被make menuconfig吓退的硬件工程师;还有那些被运维甩过来一句“你先搭个环境”的应届生——它不承诺让你成为内核开发者,但能确保你第二天就能独立完成:分区、装系统、建用户、配SSH、查日志、修权限、跑gcc编译。别被标题里的“基础”二字骗了,这本PDF里藏着的,是当年国产CPU平台起步阶段,第一批工程师真正踩过的坑、记下的参数、写死的路径。
2. 从光盘启动到图形界面:Red Hat 9.0安装全流程拆解(含GRUB配置与多系统共存实战)
2.1 安装前必须确认的四个物理层事实
这不是点下一步就能走完的向导,Linux安装的第一道门槛永远在硬件抽象层。这份教程把“安装”拆成了可验证的物理动作,而非UI点击:
磁盘命名必须肉眼确认:教程明确要求你执行
fdisk -l后,对照输出中的Disk /dev/hda: 80.0 GB, 80026361856 bytes和Device Boot Start End Blocks Id System表格,确认hda1是Windows主分区、hda2是扩展分区、hda5是你要划给Linux的逻辑分区。为什么强调“肉眼”?因为当年很多机器BIOS里IDE通道顺序和Linux识别顺序不一致,hda可能对应第二块硬盘——不亲眼核对,grub-install /dev/hda就会写错MBR。swap分区大小不是建议值,是硬约束:教程写“容量应为内存的两倍”,但没说清楚后果。实测:若物理内存512MB,只分512MB swap,在编译内核时
make -j2会触发OOM killer直接杀掉gcc进程。正确做法是执行free -m确认当前swap为0后,再运行:dd if=/dev/zero of=/swapfile bs=1M count=1024 mkswap /swapfile swapon /swapfile echo "/swapfile none swap sw 0 0" >> /etc/fstab这段代码不是补充,是教程里“swap容量”概念的落地等价物。
引导装载器位置决定你能否救回系统:教程强调“通常选MBR”,但隐藏了一个关键判断条件——如果你的Windows已占用MBR且不想破坏,就必须选“Linux分区引导扇区”。此时
grub-install命令必须指定分区而非磁盘:grub-install --root-directory=/mnt /dev/hda5参数
--root-directory=/mnt指向你挂载Linux根分区的临时路径,/dev/hda5是你的/分区设备名。漏掉--root-directory,GRUB会尝试从/读取/boot/grub/stage1,而此时系统尚未启动,必然失败。四种安装类型本质是rpm包集合策略:教程列出“个人桌面/工作站/服务器/定制”,但没说透底层差异。实测Red Hat 9.0的
anaconda安装器中,选择“服务器”类型实际执行的是:yum groupinstall "FTP Server" "Web Server" "MySQL Database"而“定制”类型则生成
/root/install.log,记录每一行rpm -ivh命令。这意味着:当你需要最小化部署时,“定制”不是选项,而是必须勾选“无图形界面”并手动剔除xorg-x11*、gnome-*等200+个包——否则装完的系统会因X服务崩溃导致init 3无法进入文本模式。
2.2 GRUB配置文件逐行解析:/boot/grub/grub.conf不是模板,是运行时黑匣子
教程提到“编辑/boot/grub/grub.conf可改变默认值”,但没告诉你哪些行改了会立即生效、哪些行改了要重装GRUB。我们以Red Hat 9.0典型配置为例:
# grub.conf generated by anaconda # # Note that you do not have to rerun grub after making changes to this file # NOTICE: You have a /boot partition. This means that # all kernel and initrd paths are relative to /boot/, eg. # root (hd0,0) # kernel /vmlinuz-version ro root=/dev/hda3 # initrd /initrd-version.img #boot=/dev/hda default=0 timeout=10 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title Red Hat Linux (2.4.20-8) root (hd0,0) kernel /vmlinuz-2.4.20-8 ro root=LABEL=/ initrd /initrd-2.4.20-8.img title Windows XP rootnoverify (hd0,1) chainloader +1default=0:索引值从0开始,对应第一个title。若新增一个内核条目在最前面,default必须同步改为1,否则仍启动旧内核。root (hd0,0):(hd0,0)表示第一块硬盘的第一个分区(GRUB计数从0开始),这与Linux的/dev/hda1对应。但注意:若你用fdisk把/boot单独分在/dev/hda2,此处必须改为(hd0,1),否则kernel /vmlinuz会找不到文件。kernel /vmlinuz-2.4.20-8 ro root=LABEL=/:ro表示只读挂载根文件系统,这是安全机制——系统启动初期禁止写入,直到init进程执行mount -o remount,rw /。若此处误写rw,某些老主板会因ext3日志未初始化直接panic。chainloader +1:调用Windows bootloader的关键指令。+1表示加载当前分区的第一个扇区(即MBR)。若Windows在/dev/hda1,而GRUB安装在/dev/hda,此行必须存在,否则按方向键选中Windows后会黑屏。
提示:修改
grub.conf后无需grub-install,但若你改动了root或kernel路径指向的分区,必须用grub命令行工具验证:grub grub> root (hd0,0) grub> kernel /vmlinuz-2.4.20-8 grub> boot此操作模拟GRUB启动流程,能在不重启情况下验证路径是否正确。
2.3 多系统共存时的致命冲突点:Windows与Linux对MBR的争夺战
教程提到“多种操作系统共存”,但没预警一个血泪经验:当Windows重装后,你的Linux将无法启动。原因在于Windows安装程序会无条件覆写MBR,删除GRUB引导代码。解决方案不是重装Linux,而是用GRUB救援:
用Red Hat 9.0安装光盘启动,进入
linux rescue模式;执行
chroot /mnt/sysimage切换到原系统根目录;重新安装GRUB到MBR:
grub-install /dev/hda注意:此处
/dev/hda是整块硬盘设备名,不是分区名。若写成/dev/hda1,GRUB会安装到分区引导扇区,Windows下次启动仍会覆盖。若
grub-install报错Error 17: Cannot mount selected partition,说明/boot分区未挂载。需先执行:mkdir /boot mount /dev/hda1 /boot # 假设/boot在hda1
这个过程在教程里被压缩成一句话,但实际耗时20分钟——因为你得先猜对/boot在哪个分区,再确认/dev/hda1是否真的包含/boot/grub目录。这就是为什么老工程师总说:“装Linux前,先给Windows做个MBR备份”。
3. 权限、链接与挂载:三个被新手反复误解的核心机制深度还原
3.1chmod数字法不是魔法,是二进制位移的直译
教程只写了chmod 755 filename,但没解释为什么7=读+写+执行。真相是:Linux权限用3位八进制数表示,每位对应一类用户(所有者/组/其他),每位的3比特分别代表r(4)、w(2)、x(1):
| 权限 | 二进制 | 八进制 |
|---|---|---|
| rwx | 111 | 7 |
| rw- | 110 | 6 |
| r-x | 101 | 5 |
| r-- | 100 | 4 |
所以chmod 755=rwxr-xr-x,而chmod 644=rw-r--r--。但教程没提一个关键陷阱:目录的x权限决定能否cd进入,而非文件能否执行。实测:
mkdir testdir chmod 644 testdir # 去掉所有者的x权限 cd testdir # 报错:Permission denied ls testdir # 却能列出内容!因为ls只需要目录的r权限正确做法是给目录加x:
chmod 755 testdir # 或更精准:chmod u+x testdir注意:
chmod -R 755 /home是高危操作!它会把所有子目录的x权限打开,包括.ssh目录——这会导致sshd拒绝登录,报错Authentication refused: bad ownership or modes for directory /home/user/.ssh。安全做法是分步:find /home -type d -exec chmod 755 {} \; # 目录统一755 find /home -type f -exec chmod 644 {} \; # 文件统一644 chmod 700 /home/*/\.ssh # 单独加固.ssh目录
3.2 硬链接与软链接的本质差异:inode才是唯一真相
教程说“硬链接指向同一个inode”,但没说清inode是什么。简单说:inode是文件系统的元数据编号,存储文件大小、权限、时间戳、数据块指针,但不存文件名。ls -i显示的就是这个编号:
$ ls -i /etc/passwd 123456 /etc/passwd $ ln /etc/passwd /tmp/passwd_hard $ ls -i /tmp/passwd_hard 123456 /tmp/passwd_hard两个文件名指向同一inode(123456),因此:
- 修改
/etc/passwd内容,/tmp/passwd_hard立即可见; rm /etc/passwd后,只要/tmp/passwd_hard存在,文件数据不会丢失(inode链接数>0);- 但硬链接不能跨文件系统:因为不同分区有独立inode编号空间,
ln /dev/sdb1/file /dev/sda1/link必然报错Invalid cross-device link。
软链接则完全不同:
$ ln -s /etc/passwd /tmp/passwd_soft $ ls -li /tmp/passwd_soft 789012 /tmp/passwd_soft -> /etc/passwd/tmp/passwd_soft自身有独立inode(789012),其数据块里只存字符串/etc/passwd。因此:
rm /etc/passwd后,/tmp/passwd_soft变成坏链接(ls -l显示红色);mv /etc/passwd /etc/passwd.bak,软链接立即失效;- 软链接可跨文件系统,因为只是路径字符串。
避坑:常见问题与排查
现象1:ln -s /opt/app /usr/local/app后,程序启动报错No such file or directory
原因:软链接目标路径是相对路径,/opt/app被移动后链接失效;或程序在chroot环境中运行,/opt未挂载。
解决:用绝对路径创建链接,并确认chroot环境已绑定挂载:mount --bind /opt /chroot/opt现象2:
cp -r /dir1 /dir2后,原目录中的软链接在/dir2里指向错误路径
原因:cp默认不解析软链接,而是复制链接文件本身。若/dir1/link指向../file,复制后/dir2/link仍指向../file,但相对位置已变。
解决:用-L参数强制跟随链接:cp -rL /dir1 /dir2现象3:
df -h显示/分区使用率100%,但du -sh /*总和远小于磁盘容量
原因:被删除但仍被进程占用的文件(如Apache日志)仍占inode,du统计的是文件系统目录树,df统计的是块使用量。这些文件在/proc/*/fd/中有引用。
解决:找出占用进程并重启:lsof +L1 # 列出已删除但仍有链接的文件 kill -USR1 $(pgrep httpd) # 优雅重启Apache释放日志文件
3.3mount不是挂载命令,而是文件系统命名空间的映射开关
教程说“挂载使我们能访问文件系统”,但没点破:mount本质是将一个设备的根目录(如/dev/hda2的/)映射到当前文件系统的某个目录节点(如/mnt/data)。这意味着:
- 挂载点目录必须为空:若
/mnt/data下已有文件,挂载后这些文件会被隐藏,卸载后才重现。这不是bug,是设计——Linux用目录作为挂载锚点。 - 挂载选项决定行为:教程没提
-o参数,但生产环境必用。例如挂载U盘:mount -t vfat -o uid=500,gid=500,umask=022 /dev/sdb1 /mnt/usbuid=500让普通用户(ID500)拥有读写权,umask=022使新建文件权限为644(666-022),否则默认umask=077导致文件仅属主可读。 /etc/fstab是持久化挂载的契约:教程提到“编辑/etc/fstab”,但没给范例。标准格式为:
第六列/dev/hda2 /home ext3 defaults 1 2 UUID=abcd-efgh /boot vfat defaults 0 22表示fsck检查顺序(/为1,其余为2,0跳过)。若此处填错,系统可能卡在fsck等待输入。
避坑:常见问题与排查
现象1:mount /dev/sdb1 /mnt/usb报错wrong fs type, bad option, bad superblock
原因:U盘文件系统非vfat(如exFAT),或superblock损坏。
解决:先用file -s /dev/sdb1探测文件系统类型,再指定-t参数;若superblock损坏,用备份块修复:dumpe2fs /dev/sdb1 | grep -i superblock # 查找备份superblock位置 e2fsck -b 32768 /dev/sdb1 # 用备份块修复现象2:NFS挂载后,
ls /mnt/nfs卡住无响应
原因:NFS服务器宕机或网络中断,客户端默认hard挂载会无限重试。
解决:强制卸载并用soft+timeo参数重挂:umount -f -l /mnt/nfs mount -t nfs -o soft,timeo=10,retry=3 server:/export /mnt/nfs现象3:
df -h显示/mnt/data使用率100%,但du -sh /mnt/data/*总和只有50%
原因:挂载点下存在隐藏的已删除文件(如/mnt/data/.log被rm但进程仍在写)。
解决:检查该挂载点下被删除的文件:lsof +L1 | grep "/mnt/data"
4. 从ls到grep:终端里真正高效的文件操作链式工作流
4.1ls的长格式输出不是装饰,是权限审计的原始日志
教程列出ls -l各列含义,但没告诉你如何用它快速定位风险。ls -l输出:
drwxr-xr-x 5 root root 1024 Sep 13 03:27 Desktop -rw-r--r-- 1 root root 737 Oct 7 18:42 a.txt其中第三、四列(root root)是所有者和组,第五列(1024)是大小,第六七列(Sep 13 03:27)是修改时间。但关键在第一列权限字符串:
d开头是目录,-是文件,l是软链接——这决定了你能对它做什么;- 后9位分三组:
rwxr-xr-x→ 所有者(rwx)、组(r-x)、其他(r-x); - 权限位中的
x对目录意味着“可进入”,对文件意味着“可执行”。所以chmod 644 script.sh后,./script.sh会报错Permission denied,必须chmod +x script.sh。
更实用的技巧:用ls -lt按修改时间倒序排列,快速找到最新日志:
ls -lt /var/log/*.log | head -5 # 最近5个日志文件用ls -ltr正序排列,找最老的备份:
ls -ltr /backup/*.tar.gz | head -1 # 最早的备份4.2find不是搜索工具,是文件系统状态的手术刀
教程只写find /home -name "*.log",但生产环境必须掌握精确控制。find核心能力是组合条件+执行动作:
- 按时间精准定位:找72小时内修改的
.conf文件(用于审计配置变更):find /etc -name "*.conf" -mmin -4320 -ls # -mmin -4320 = 72小时 - 按大小清理垃圾:删掉
/tmp下大于100MB的文件:
注意find /tmp -type f -size +100M -delete+100M表示“大于100MB”,-100M才是“小于100MB”。 - 按权限修复隐患:找所有世界可写的目录(安全风险):
find / -type d -perm -002 -ls # -perm -002 匹配其他用户有w权限的目录 - 执行复杂动作:对所有
.sh文件添加执行权限,并记录操作:find /opt/scripts -name "*.sh" -exec chmod +x {} \; -exec echo "Fixed: {}" >> /var/log/fix_sh.log \;
避坑:常见问题与排查
现象1:find /home -name "*.txt" -delete后,部分文件未被删除
原因:-delete动作要求父目录有w权限,若/home/user权限为755(组和其他无w),find无法删除其子文件。
解决:先加权限再删除,或用-exec rm {} \;(需父目录x权限):find /home -name "*.txt" -exec chmod 755 {} \; -delete现象2:
find /var/log -mtime -1找不到今天生成的日志
原因:-mtime -1表示“24小时内修改”,但mtime基于inode修改时间,日志轮转时可能只改名不改mtime。
解决:用-newermt按绝对时间比较:find /var/log -newermt "2023-10-01 00:00:00" -name "*.log"现象3:
find / -name "java"执行几小时无结果,且系统变慢
原因:/proc、/sys等虚拟文件系统会阻塞find遍历。
解决:排除虚拟文件系统:find / -path "/proc" -prune -o -path "/sys" -prune -o -name "java" -print
4.3grep链式过滤:从日志海洋中打捞关键证据
教程说“在文件中搜索特定模式”,但没教如何应对真实日志的噪声。以/var/log/messages为例:
- 基础过滤:找所有
kernel:相关行(内核消息):grep "kernel:" /var/log/messages - 反向过滤:排除
avahi(零配置网络服务)的噪音:grep "kernel:" /var/log/messages | grep -v "avahi" - 上下文关联:找
Out of memory前后10行(定位OOM killer日志):grep -A 10 -B 10 "Out of memory" /var/log/messages - 正则精炼:匹配IP地址(避免匹配到端口号):
grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" /var/log/secure-E启用扩展正则,([0-9]{1,3}\.){3}匹配前三段,[0-9]{1,3}匹配最后一段。
最狠的招:用grep配合awk提取字段。比如从ps aux中提取CPU使用率>80%的进程:
ps aux --sort=-%cpu | awk '$3 > 80 {print $2, $3, $11}' | head -5$3是CPU列,$2是PID,$11是COMMAND,--sort=-%cpu按CPU降序。
5. 用户、组与Shell:Linux多用户体系的权限控制闭环
5.1/etc/passwd不是用户数据库,是登录会话的启动说明书
教程列出/etc/passwd格式,但没说每字段的运行时意义。一行示例:
z3:x:501:501:z3 user:/home/z3:/bin/bash:/bin/bash- 第1字段
z3:登录名,su z3时输入的名称; - 第2字段
x:密码占位符,真实密码在/etc/shadow(需root读); - 第3字段
501:UID,root必须为0,普通用户UID≥500(RHEL规范); - 第4字段
501:GID,对应/etc/group中gid=501的组; - 第5字段
z3 user:GECOS字段,finger z3时显示的描述; - 第6字段
/home/z3:家目录,cd或~指向的位置; - 第7字段
/bin/bash:登录Shell,/sbin/nologin表示禁止交互登录(如apache用户)。
关键陷阱:UID重复会导致权限混乱。若手动编辑/etc/passwd添加用户时UID设为0,该用户将获得root权限,但sudo日志无法追踪。正确做法永远用useradd:
useradd -m -s /bin/bash -c "z3 user" z3 passwd z3 # 设置密码-m自动创建家目录,-s指定shell,-c写GECOS。
5.2 组管理不是附加功能,是权限分配的杠杆支点
教程提到“用户组”,但没讲清/etc/group的杠杆作用。一行示例:
developers:x:502:z3,l4z3,l4是该组成员,但组权限生效需满足两个条件:
- 文件所属组为
developers(chgrp developers filename); - 文件组权限位有对应权限(如
-rw-rw-r--中的rw-)。
生产环境最佳实践:用组实现最小权限。例如Web开发团队:
groupadd webdev usermod -a -G webdev z3 usermod -a -G webdev l4 chgrp -R webdev /var/www/html chmod -R g+rw /var/www/html chmod g+s /var/www/html # setgid,新文件继承组g+s让目录具有setgid属性,其下新建文件自动归属webdev组,避免chgrp手工干预。
5.3 Bash Shell不是命令行,是进程环境的中央控制器
教程说“bash是默认shell”,但没揭示它如何控制进程生命周期。.bashrc和.bash_profile的区别是高频翻车点:
.bash_profile:登录Shell(如SSH登录、su -)时执行一次;.bashrc:交互式非登录Shell(如GNOME终端新开标签页)时执行。
因此,环境变量必须放在.bash_profile中,否则ssh user@host 'echo $PATH'会得到默认PATH。而别名(alias)可放.bashrc,因为ls别名在任何终端都该生效。
一个血泪教训:某次部署Java应用,JAVA_HOME设在.bashrc,导致crontab任务失败(cron使用/bin/sh,不读.bashrc)。正确做法:
# 在 ~/.bash_profile 中 export JAVA_HOME=/usr/java/jdk1.8.0_202 export PATH=$JAVA_HOME/bin:$PATH # 然后在 ~/.bashrc 中 source 它 if [ -f ~/.bash_profile ]; then . ~/.bash_profile fi避坑:常见问题与排查
现象1:su z3后,echo $PATH显示旧值,which java找不到JDK
原因:su z3不启动登录Shell,不读.bash_profile,只读.bashrc。
解决:用su - z3(带短横线),强制登录Shell。现象2:
sudo -u z3 bash -c 'echo $HOME'输出/root而非/home/z3
原因:sudo默认不重置环境变量,$HOME继承自root。
解决:用-H参数重置HOME:sudo -H -u z3 bash -c 'echo $HOME'现象3:脚本中
#!/bin/bash,但执行时报错command not found
原因:脚本有Windows换行符(\r\n),bash解析失败。
解决:用dos2unix转换,或用sed:sed -i 's/\r$//' script.sh
6. 从gcc到make:构建自动化链条的底层逻辑与调试心法
6.1gcc不是编译器,是预处理、编译、汇编、链接四阶段流水线
教程只写gcc hello.c -o hello,但每个参数都对应一个阶段。分解如下:
gcc -E hello.c -o hello.i # 预处理:展开#include、宏定义,生成.i gcc -S hello.i -o hello.s # 编译:转成汇编代码.s gcc -c hello.s -o hello.o # 汇编:生成目标文件.o(二进制) gcc hello.o -o hello # 链接:合并.o和库,生成可执行文件关键洞察:.o文件不依赖源码,但依赖头文件声明。若hello.c包含#include "math.h",而math.h被修改,gcc -c hello.o不会重新编译——除非用-M生成依赖关系:
gcc -M hello.c # 输出:hello.o: hello.c /usr/include/math.h6.2Makefile不是语法糖,是依赖图的显式声明
教程提到makefile,但没给可运行的最小实例。一个健壮的Makefile必须包含:
CC = gcc CFLAGS = -Wall -g TARGET = hello OBJS = hello.o utils.o $(TARGET): $(OBJS) $(CC) $(CFLAGS) -o $@ $^ %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f $(TARGET) $(OBJS) .PHONY: clean$@:目标名(hello);$^:所有依赖(hello.o utils.o);$<:第一个依赖(hello.c);.PHONY: clean:声明clean是伪目标,避免与同名文件冲突。
调试技巧:用make -n打印将执行的命令而不执行,用make -d输出详细依赖分析。
6.3ssh与samba不是网络工具,是文件系统边界的延伸
教程并列ssh和samba,但它们解决的是不同维度的问题:
ssh:通过sshfs将远程目录挂载为本地文件系统:sshfs user@server:/home/user /mnt/remote -o allow_other ls /mnt/remote # 像本地目录一样操作优势:加密传输,无需额外服务端配置(只要sshd开启)。
samba:提供SMB协议,让Linux像Windows共享一样被访问:# /etc/samba/smb.conf [shared] path = /srv/shared read only = no valid users = z3启动
smbd后,Windows资源管理器输入\\linux-server\shared即可访问。
二者选型原则:内部开发用sshfs(安全、轻量),跨平台协作用samba(兼容性好)。
从那以后我每次配新环境,都会先跑一遍ssh -T git@github.com验证密钥,再用sshfs挂载代码仓库——因为真正的效率不是命令多快,而是你敢不敢在终端里直接vim改远程文件,保存即生效。希望帮到你。
本文还有配套的精品资源,点击获取