在信息技术日新月异的今天,Linux操作系统凭借其开源、稳定、高效及强大的可定制性,已成为云计算、大数据、容器化及企业级服务器领域的绝对基石。无论是系统运维工程师、开发测试人员,还是安全架构师,扎实的Linux基础都是不可或缺的核心竞争力。然而,理论与实践之间往往存在一道需要亲手敲击键盘才能跨越的鸿沟。
本书(/本练习集)正是基于这一初衷而设计。它并非一本冗长枯燥的理论教材,而是一份“手把手”式的实战操作指南。我们精心设计了覆盖十大核心知识模块的近百道实操题目,从最基础的命令行入门,到用户权限管理、文本处理、网络配置,再到复杂的Shell脚本编程,旨在通过“在做中学”的方式,帮助您将零散的命令记忆转化为系统性的解决能力。
本练习集的特点如下:
致学习者的一封信:Linux的学习没有捷径,唯一的捷径就是——多练、多错、多查、多思。请务必在真实的虚拟机或云服务器上亲自动手操作,不要仅仅停留在“看一遍命令”的程度。当您遇到报错时,请冷静阅读错误信息,善用man和--help,那是您最好的老师。
准备好了吗?打开您的终端,让我们从敲下第一行date命令开始,开启这段充满挑战与收获的Linux进阶之旅吧!
使用date命令显示当前时间,并将其格式化为“年-月-日 时:分:秒”(例如2026-06-08 14:30:25)。
使用cal命令查看2025年10月的日历,并输出到终端。
通过history查看最近执行的5条命令,然后使用!符号重新执行倒数第3条命令。
使用whatis查看ls命令的简短描述,并解释输出结果。
如果没有结果用mandb更新数据索引
使用man命令查看passwd命令的手册页,找到“-d”选项的作用,并写出该选项的功能。删除用户密码

使用ls --help查看ls命令的帮助信息,找出显示隐藏文件的选项。
利用Tab键补全:在终端输入/etc/syscon后按Tab键,写出补全后的完整路径。/etc/sysconfig/
使用su -切换到root用户,观察命令提示符的变化;然后切换回普通用户。
使用echo命令输出字符串“Hello Linux”,并通过!$再次执行上一条命令的最后一个参数。
使用Ctrl+R搜索历史命令中包含“date”的命令,并执行搜索到的命令。
pwd查看当前工作目录,然后用cd /var/log进入该目录,再使用cd -返回上一个目录。
mydir的目录,并在其中创建一个空文件readme.txt。
cp命令将/etc/passwd复制到/tmp/mydir/下,并保持原文件的权限和时间戳。
mv命令将/tmp/mydir/passwd重命名为/tmp/mydir/userlist。
rm -i交互式删除/tmp/mydir/userlist,确认删除。
touch命令创建文件/tmp/test.txt,然后查看它的时间戳(使用stat),再修改文件内容(可用echo "hello" > /tmp/test.txt),最后再次查看时间戳的变化。
ls -l查看/tmp/mydir目录的详细属性,解释输出中第一列(如drwxr-xr-x)每一字符的含义。文件 ,所有者权限,所属组权限,其他权限,所有者,所属组,大小,时间戳
file命令查看/bin/ls的文件类型,并解释输出。文件类型:<font style="color:rgb(15, 17, 21);background-color:rgb(235, 238, 242);">ELF 64-bit LSB pie executable</font> —— 这是一个 64位 ELF 格式的可执行文件x86架构了解这些就行,其他的扩展
/home,使用相对路径进入/home/user/Desktop(假设user存在)。
ls -ld /查看根目录的权限和属性。
devops,指定其UID为1500,家目录为/home/devops_home。
userdel删除用户devops,并同时删除其家目录和邮件池。
webgroup,GID为3000,然后将用户devops加入到该组作为附加组。
passwd命令锁定用户devops,然后尝试以devops登录(或查看/etc/shadow中该用户密码字段的变化)。
chage命令强制用户devops在下次登录时修改密码。
/tmp/test.txt的权限为:属主可读可写可执行,属组可读可执行,其他人无任何权限(使用数字方式)。
/tmp/mydir目录及其所有子文件递归设置属主为devops,属组为webgroup。
/tmp/test.txt增加属组的写权限,并去掉其他人的执行权限。
tom和jerry,并创建一个共享目录/share,要求:属主为tom,属组为tomgroup,tom和jerry都可以在/share中创建和删除文件,其他用户不能访问。写出完整步骤。
/etc/passwd和/etc/shadow文件中root用户的信息,解释各字段含义。#/etc/passwd#用户名:密码占位符:UID:GID:用户描述信息:家目录:登录shellroot:x:0:0:Super User:/root:/bin/bash#etc/shadow#用户名:密码:最后一次修改的时间:最小密码修改时间:密码有效期:密码过期提醒时间:密码过期可宽限时间:预留字段:预留字段root:$6$BTPIxoq7$V9Ll2i/IM6.ziTYjV45qe/FQ7crZLepZM4cncuigPmhkf24EykrLX0TLeVDbNmJ6l0uopFTVH07gdiCkDKqc3.:20603:0:99999:7:::
将ls -l /var的输出重定向到文件/tmp/ls_output.txt中,同时将错误信息(如果有)丢弃(重定向到/dev/null)。
使用cat命令将/etc/hosts文件的内容作为输入,通过管道传递给wc -l统计行数。
使用tee命令将ps aux的输出同时显示在屏幕上并保存到/tmp/ps.log文件中。
使用tr命令将/etc/passwd中的所有小写字母转换为大写,并输出到屏幕(不修改原文件)。
从键盘输入多行内容(直到输入END为止),使用mail命令(假设已安装)发送给自己或一个测试邮箱(模拟场景即可,写出命令格式)。
mail -s "邮件主题" 收件人地址 << END这里是第一行内容这里是第二行内容...END/tmp/hello.txt,然后使用输入重定向将其作为cat的输入显示出来。
/etc目录下所有以.conf结尾的文件,将正确输出保存到/tmp/find_ok.txt,将错误输出(如权限拒绝)保存到/tmp/find_err.txt。
/etc/passwd中的行数)。
先创建/tmp/test.txt文件内容
this is first line old error test content old third line error info old normal fourth line text delete this fifth line target random text no keyword old string here, another error end base contentvim打开/tmp/test.txt,在命令模式下移动光标到第5行,然后删除该行。dd删除即可
vim中复制第1行到第3行,并粘贴到文件末尾。3yy复制p粘贴
vim中查找字符串“error”,并依次跳转到下一个匹配项。搜索yong "/"反斜杠,下一项用n,上一项用N
vim的替换功能将文件中所有的“old”替换为“new”(全局替换)。

vim中开启行号显示,然后保存文件并退出。
vim的可视化模式(按v)选中一个矩形区域,然后删除该区域内容。
vim中同时打开/etc/passwd和/tmp/test.txt两个文件,水平分割窗口,并在两个窗口间切换。
vim异常退出产生的.swp文件:模拟异常退出(例如vim /tmp/test.txt后杀掉终端),然后重新打开并按照提示恢复文件。

head和tail命令组合显示/etc/passwd的第15到第20行。
grep查找/etc/passwd中包含“root”的行,并显示行号。
grep查找/etc/services中不包含“#”注释的所有行,并统计行数。
cut命令以冒号为分隔符,提取/etc/passwd中的用户名(第一列)和登录shell(最后一列)。
sort对/tmp/numbers.txt(内容为随机数字,每行一个)进行数字排序,并去重。
uniq统计/tmp/words.txt中每个单词出现的次数(先排序再统计)。applebananaappleorangebananaapplepearorangeapple
使用diff比较两个文件/tmp/a.txt和/tmp/b.txt,输出差异。
使用vimdiff比较/tmp/a.txt和/tmp/b.txt,观察不同之处。
使用tr删除/tmp/b.txt文件中的所有空格和制表符。
使用sed命令打印/etc/passwd的第10行到第20行。
使用sed替换/tmp/file.txt中的所有数字([0-9])为#,并直接修改原文件(使用-i选项)。
cat > /tmp/file.txt <<EOFabc123test456789hello000no number herex1y2z3987EOF
grep的正则表达式匹配/etc/passwd中以“a”开头并以“n”结尾的用户名行。
MYNAME=Linux,然后在一个子shell中(通过(echo $MYNAME))测试该变量是否有效,解释原因。本地变量只在当前shell有效,bash开启一个新的shell,所以为空
MYNAME导出为环境变量,然后执行bash进入子shell,再次echo $MYNAME。
alias创建一个别名lls,使其执行ls -l,然后取消该别名。
PATH环境变量,将/tmp/mybin目录添加到搜索路径的最前面,并验证。
history命令清除当前会话的历史记录,并强制将内存中的历史写入.bash_history。
file1.txt、file2.txt、file3.txt,并查看。
/etc下所有以.conf结尾并且文件名包含数字的文件。
.txt文件的内容追加到一个all.txt文件中(使用循环或通配符)。
PS1变量值,并临时修改提示符为\u-\h:\w>>> ,然后恢复。
source命令执行一个包含cd /var的脚本,观察当前目录是否改变;然后使用bash执行同样脚本,对比区别。cat > cd_test.sh <<EOF#!/bin/bashcd /varpwdEOF# 添加执行权限chmod +x cd_test.sh
ps命令查看当前终端下所有进程的PID、PPID、CPU和内存占用率。
top命令动态查看进程,然后按M键按内存使用率排序,按q退出。
pgrep查找所有sshd相关的进程PID。
kill命令向一个后台运行的sleep 1000进程发送SIGTERM信号,然后发送SIGKILL强制结束。
ping 8.8.8.8进程并放入后台(使用&),然后使用jobs查看作业,将其调回前台并中止。
renice调整一个正在运行的进程(例如sleep 1000)的nice值为10,然后查看其优先级变化。
pkill根据进程名杀死所有firefox进程(假设有)。
ps结合--sort选项,按内存占用降序显示前5个进程。
ip addr命令查看本机所有网络接口的IP地址,并写出其中一张网卡的MAC地址。00:0c:29:0e:ed:de
nmcli命令显示所有网络设备的状态,并激活一个名为ens160(或你的网卡名)的连接。
ens160添加一个IP地址192.168.100.10/24(使用ip命令),然后删除该地址。
nmtui图形化工具(在终端运行)配置静态IP地址,要求:IP=192.168.1.100/24,网关=192.168.1.1,DNS=8.8.8.8。

myserver,并确保重启后依然生效。
/etc/hosts文件,添加一条解析:127.0.0.1 mylocal.test,然后使用ping mylocal.test测试。
ss -tlnp命令查看当前系统监听的TCP端口,并找出哪个进程占用了22端口。
route -n查看默认网关,并添加一条静态路由:去往10.0.0.0/8的下一跳为192.168.1.254。
#!/bin/bash,脚本内输出“Hello World”,然后以三种不同方式执行该脚本(相对路径、绝对路径、bash执行)。

user_add.sh,接受一个用户名作为位置参数,创建该用户并设置随机密码(密码可使用openssl rand -base64 12生成),并显示密码。

read命令编写交互式脚本,提示用户输入两个数字,然后输出它们的和。

check_file.sh,检查/tmp/testfile是否存在,如果存在则输出“文件存在”,否则输出“文件不存在”。
case语句编写脚本grade.sh,根据用户输入的成绩(0-100)输出等级:A(85-100)、B(70-84)、C(60-69)、D(0-59)。

for循环脚本,批量创建用户user1到user10,并设置初始密码为123456(提示:使用chpasswd或passwd --stdin)。

ping_scan.sh,扫描192.168.1.1到192.168.1.254,使用ping -c 1 -W 1检测在线主机,输出在线IP列表。

while循环脚本,逐行读取/etc/passwd文件,输出每行的用户名和UID。

until循环脚本,从1加到100,输出总和。
menu.sh,显示菜单:1.显示日期 2.显示当前用户 3.退出,根据用户输入的数字编号执行对应操作,直到选择退出。



#!/bin/bashwhiletruedoecho"========== 功能菜单 =========="echo"1. 显示日期"echo"2. 显示当前用户"echo"3. 退出"echo"=============================="read -p "请输入你的选择(1/2/3):" numcase$numin 1)echo"当前系统日期时间:" dateecho"-----------------------------" ;; 2)echo"当前登录用户:$USER"echo"-----------------------------" ;; 3)echo"程序退出,再见!"exit 0 ;; *)echo"输入错误!请输入 1、2 或 3"echo"-----------------------------" ;;esacread -p "按回车继续..." cleardonebreak和continue:编写一个循环输出1到10,但当数字等于5时跳过(continue),当数字等于8时终止(break)。
#!/bin/bash# 循环1~10for ((i=1; i<=10; i++))doif [ $i -eq 5 ]; then# 等于5时跳过本次循环continuefiif [ $i -eq 8 ]; then# 等于8时终止整个循环echo"遇到数字 $i,退出循环"breakfi# 不满足上面两个条件才输出echo"当前数字:$i"doneecho"循环结束"backup.sh,将/home目录打包压缩为/backup/home_$(date +%Y%m%d).tar.gz,如果打包成功则输出“备份成功”,否则输出“备份失败”(使用exit码判断)。

#!/bin/bashBACK_FILE="/backup/home_$(date +%Y%m%d).tar.gz"mkdir -p /backuptar -zcf "$BACK_FILE" /homeret=$?if [ $ret -eq 0 ]; thenecho"备份成功"elseecho"备份失败"fi扩展: