在当今以数据驱动和自动化为核心的技术浪潮中,无论是进行大规模数据处理、构建机器学习流水线,还是管理复杂的服务器集群,对Linux操作系统的熟练掌握已成为一项不可或缺的基础技能。而Shell,作为用户与Linux内核交互的桥梁,不仅是执行命令的窗口,更是实现系统自动化、提升工作效率的强大工具。本文将系统性地剖析Linux操作系统的基本概念,深入讲解Shell命令的实战用法,并引导你步入Shell脚本编程的大门,为你后续探索更广阔的领域,如利用Shell脚本调度深度学习任务或处理自然语言处理(NLP)的数据预处理,打下坚实的基础。
一、Linux操作系统与Shell核心概念
要精通Shell,首先需要理解它所处的生态系统。Linux操作系统本质上是一个系统软件,其核心价值在于抽象和统一。它屏蔽了底层五花八门的硬件差异(如不同的CPU架构、存储设备),为上层应用程序提供了一个稳定、一致的运行环境和调用接口。这使得开发者无需为每一种硬件编写特定代码,极大地促进了软件的兼容性和可移植性。

Linux的应用领域极其广泛,从支撑互联网的服务器、嵌入式设备(如路由器、智能家居),到我们日常使用的Android手机,其底层都离不开Linux内核。这个内核负责管理计算机的核心资源:
- 内存管理:高效分配和回收系统内存。
- 文件系统管理:组织和管理磁盘上的数据。
- 任务调度:决定CPU时间如何分配给各个运行中的程序(进程)。
- 进程通信:协调不同进程之间的数据交换。
- 设备驱动:管理与硬件设备的通信。
而Shell,则是我们与这个强大内核沟通的“翻译官”和“保护层”。它主要扮演两个关键角色:
- 命令解释器:接收用户输入的命令(如
ls,grep),将其解析并转换为内核能够理解的低级系统调用请求。 - 内核保护者:用户不直接操作脆弱的内核,所有请求都经过Shell中转,这避免了因误操作直接导致系统崩溃的风险。
此外,库函数(如C标准库)在系统调用之上提供了更友好、更高级的封装。例如,程序员使用printf函数来打印内容,而不必关心底层是如何与屏幕驱动交互的。这种封装不仅简化了开发,还提供了良好的跨平台兼容性。
Unix | 经典老牌,现代 OS 鼻祖 |
Linux | 高效运行、开源免费,内核基于 Unix 思想开发 |
| Windows | 视窗界面友好 |
二、Shell命令实战:高效操作的核心技巧
掌握Shell命令是驾驭Linux系统的第一步。命令通常遵循“命令名 [选项] [参数]”的格式。下面我们将聚焦于一系列能极大提升生产力的核心命令和概念。
command [options] [arguments]
options:选项,用于调整命令行为,短选项用-开头(如-n),长选项用--开头(如--help),多个短选项可合并(cat -n -v = cat -nv)
arguments:参数,命令操作的对象(如文件名、路径、字符串),是可选部分
格式中[]代表可选内容,不是命令的一部分,输入时无需书写1. 文件查看与内容筛选
对于文本文件,我们有多种查看方式:cat用于快速查看整个小文件;head和tail则专注于查看文件的开头或末尾部分,在查看日志时尤其有用。
cat filename # 查看文件全部内容
cat -n filename # 显示行号(包含空行)
cat -b filename # 显示行号(跳过空行)head -n 10 filename # 查看文件前10行(-n可省略,直接写 head -10 filename)
tail -n 10 filename # 查看文件后10行
tail -f filename # 实时追踪文件新增内容(查看日志必备,如服务运行日志)真正的威力来自于命令的组合。管道符 `|` 允许你将一个命令的输出作为另一个命令的输入。例如,你可以先列出所有进程,然后筛选出包含“python”的行:ps aux | grep python。这在分析AI模型训练时的进程资源占用时非常实用。
# 筛选文件前10行中包含指定字符串的内容
head -n 10 filename | grep "字符串"
# 筛选头文件末尾10行中包含extern的内容
tail -n 10 /usr/include/stdio.h | grep "extern"
# 查看系统中与bash相关的进程信息
ps -ef | grep bash配合管道,`grep`命令成为了文本搜索的利器。它支持强大的正则表达式,可以精准地过滤出你需要的信息行。
# 在指定文件中搜索字符串
grep "目标字符串" 文件名
grep -i "字符串" filename # 忽略大小写搜索
grep -v "字符串" filename # 反向匹配,输出不包含该字符串的行
grep -n "字符串" filename # 显示匹配行的行号
grep -c "字符串" filename # 仅统计匹配的行数2. 输入输出重定向与通配符
Shell默认将命令输出显示在终端(标准输出)。重定向可以改变这种流向,比如将输出保存到文件,或从文件读取输入。这对于保存命令结果、生成配置文件或批量处理数据至关重要。
| 符号 | 作用 | 示例 |
|---|---|---|
| 覆盖重定向 | 若文件不存在则创建,存在则清空原有内容后写入 | |
| 追加重定向 | 若文件不存在则创建,存在则在文件末尾追加内容 |
echo "hello" > test.txt # 覆盖写入test.txt
echo "world" >> test.txt # 追加内容到test.txt# 正常方式:grep从文件读取
grep "error" log.txt
# 输入重定向方式:功能完全一样!
grep "error" < log.txt通配符(如*, ?, [])则用于匹配文件名,实现批量操作,例如删除所有以`.log`结尾的文件:rm *.log。
| 通配符 | 含义 | 示例 |
|---|---|---|
| 匹配任意长度、任意字符(包含空字符) | 匹配所有 txt 文件 | |
| 匹配单个任意字符 | 匹配 file1.txt、filea.txt | |
| 匹配括号内任意一个字符 | 仅匹配 file1/2/3.txt | |
| 匹配不在括号内的单个字符 | 排除数字命名文件 |
3. 权限、压缩与查找
Linux的权限系统(rwx)是系统安全的基础。chmod, chown, chgrp命令用于管理文件和目录的访问权限。
| 权限 | 符号 | 数字权重 | 含义 |
|---|---|---|---|
| 读 | 4 | 读取文件内容 / 查看目录结构 | |
| 写 | 2 | 修改文件内容 / 在目录内增删文件 | |
| 执行 | 1 | 执行脚本 / 进入目录 |
权限的数字表示法(如755)是权重相加:读(4)、写(2)、执行(1)。例如,表示属主有全部权限,属组和其他用户只有读和执行权限。rwx=4+2+1=7
chmod 0777 filename
# 三位数字依次对应:属主、属组、其他用户 权限
# 0为特殊权限位,日常使用可省略,直接写 chmod 755 filename
chmod u+x filename # 给属主添加执行权限
chmod g-w filename # 给属组移除写权限
chmod a=r filename # 所有用户(u/g/o)统一设置为只读权限
#加-R选项递归修改目录下所有子文件 / 子目录权限,包括目录自身
chmod -R 755 test_dir/rwx:创建文件的用户对文件是否拥有读写执行的权限
rwx:创建文件的同组用户对文件是否拥有读写执行的权限
rwx:其余人是否拥有读写执行的权限
# 查看所有组
cat /etc/group
sudo chgrp 组名 filename # 修改文件所属组,组必须存在chown 用户名 filename # 仅修改文件属主,也必须存在
chown 用户名:组名 filename # 同时修改属主和属组(常用)在数据传输和归档时,压缩和解压缩命令(tar, gzip)必不可少。它们能有效减少存储空间和网络传输时间。
| 参数 | 作用 |
|---|---|
| create,创建归档 / 压缩包(压缩必备) | |
| extract,解压归档 / 压缩包(解压缩必备) | |
| verbose,显示压缩 / 解压的详细过程(可选,方便查看进度) | |
| file,指定压缩包文件名,必须放在所有参数最后一位 | |
| 调用算法,对应/格式 | |
| 调用算法,对应/格式 |
# 压缩为 .tar.gz 格式(gzip,压缩速度快,使用率最高)
tar -zcvf filename.tar.gz dirname/
# 压缩为 .tar.bz2 格式(bzip2,压缩率更高,速度稍慢)
tar -jcvf filename.tar.bz2 dirname/
tar -zcvf /target/archive.tar.gz source/ 压缩到指定目录,直接指定输出文件路径注意:可简写为dirname/*。dirname/参数必须紧跟在压缩包名之后。-f
# 解压 .tar.gz 格式
tar -zxvf filename.tar.gz
# 解压 .tar.bz2 格式
tar -jxvf filename.tar.bz2
# 解压到指定目录(-C 参数,大写C)
tar -zxvf filename.tar.gz -C /home/test/当需要寻找特定文件时,`find`命令功能无比强大,可以根据名称、类型、大小、修改时间等属性进行精准查找。
find [搜索起始目录] [匹配条件] "文件名"
# 精确查找文件(区分大小写)
find /home -name "test.txt"
# 忽略大小写查找(-iname,更常用)
find /home -iname "TEST.txt"
# 结合通配符模糊查找
find /etc -name "*.conf" # 查找所有.conf后缀配置文件
find /home -type f # 只查找普通文件,排除目录
find /home -type d # 只查找目录
find /home -size +100M # 查找大于100MB的文件 100k(小写)
find /home -mtime -7 # 查找7天内修改过的文件4. 系统监控与包管理
其他常用命令构成了日常系统维护的工具箱:ps和top用于监控进程;ifconfig(或现代的ip命令)和ping用于网络调试;du和df用于查看磁盘使用情况。
echo "Hello Linux" # 输出固定字符串
echo $PATH # 输出系统环境变量PATH的值
echo -n "无换行输出" # -n:取消末尾自动换行
echo "追加内容" >> test.txt # 结合追加重定向写入文件du -h # 人性化显示单位(KB/MB/GB,最推荐使用)
du -m # 以MB为单位显示大小
du -k # 以KB为单位显示大小
du -sh dirname/ # 统计目录总大小,不展示子文件详情(高频用法)
sudo fdisk -l # 列出系统所有磁盘及分区信息(含容量、格式、挂载点)sudo [需要提权的命令]示例:sudo vim /etc/hosts
date # 查看当前系统时间(默认格式)
date "+%Y-%m-%d %H:%M:%S" # 自定义格式:年-月-日 时:分:秒
whoamips -ef # 查看系统所有进程完整信息(含PPID父进程ID、用户、命令等)
ps aux # BSD格式展示进程,是Linux下更通用的写法,展示内容更全面top # 直接执行进入监控界面
q:退出 top 界面
M:按内存占用率排序
P:恢复按 CPU 使用率排序
ifconfig # 查看所有激活网卡的信息
ip addr #推荐使用ping www.baidu.com # 测试与百度服务器连通性
ping 192.168.1.1 # 测试局域网内设备连通性
ping -c 4 www.baidu.com # -c:指定发送数据包数量,发送4次后自动停止(避免无限ping)在软件安装方面,Debian/Ubuntu系列主要使用dpkg和apt-get(或apt)。是底层工具,用于安装本地dpkg包;而.deb(或apt-getapt)是高级工具,能自动解决依赖关系,从软件源在线安装。[AFFILIATE_SLOT_1]
#安装软件
sudo dpkg -i filename.deb # -i=install
#查看软件是否安装成功(已安装的软件)
dpkg -l | grep 软件名
#彻底卸载软件(删除配置)
sudo dpkg -p 软件名 # -P=purge,彻底删除程序 + 配置文件
#仅卸载软件(保留配置)
dpkg -r 软件名 #-r=remove,删除程序,保留配置文件注意:若因依赖失败,可尝试dpkg -i。sudo apt-get install -f
可以自己根据配置的源下载对应的软件
根据软件依赖关系安装软件所需要的所有依赖
1、网络检测,先查看是否可以上网:
ping 8.8.8.8 # 检测外网连通性,正确
ping -c 4 8.8.8.8 # 推荐用法:发送4个包后自动停止,避免无限ping
若无法上网,则:
(1)让虚拟机使用NAT模式:
点击“虚拟机”点击”设置“
点击“虚拟网络适配器”
选择“NAT模式”
点击“确认”
(2)修改Ubuntu配置文件
打开配置文件:
sudo vim /etc/network/interfaces
修改配置文件为如下格式:
auto lo
iface lo inet loopback
auto ens33
iface ens33 inet dhcp
保存退出
:wq
(3)重启Ubuntu
sudo reboot / sudo shutdown -r now
2、配置apt-get工具集的源
(1)点击“Ubuntu Software”
(2)右键选择“Software & Updates”
(3)「Download from」选择「Other」,筛选国内镜像源,源选择 aliyun
(4)点击“close”
(5)输入命令
sudo apt-get autoclean # 清理旧版本安装包缓存
sudo apt-get update # 刷新软件源缓存(必须执行,同步最新软件列表)
sudo apt-get install -f # 修复系统中缺失的依赖包
3、软件安装
#安装软件
sudo apt-get install 软件名 #自动处理依赖
#彻底卸载软件
sudo apt-get remove 软件名 --purge
sudo apt-get purge 软件名
#卸载软件(保留配置)
sudo apt-get remove 软件名
三、Shell脚本编程入门:自动化之力
Shell脚本是将一系列命令、控制结构和变量组织在一个文件中,以实现自动化任务的编程方式。它是一种解释型语言,无需编译,由Shell逐行解释执行,特点是开发快捷、灵活,非常适合系统管理、文件批量处理和任务自动化。
1. 脚本基础与变量
一个简单的Shell脚本以#!/bin/bash(Shebang)开头,指定解释器。脚本需要赋予执行权限(chmod +x script.sh)后才能运行。
#脚本首行规范:必须添加解释器声明
#!/bin/bash
# 这是注释,# 开头的行不会被执行
# 1. 编辑脚本(推荐指定bash解释器)
vim test.sh
# 2. 添加执行权限
chmod +x test.sh
# 3. 相对路径执行(运行)
./test.shShell中的引号有不同含义:单引号保持所有字符原样;双引号允许变量和命令替换;反引号或$(...)用于执行命令并捕获其输出。
echo "当前路径:$(pwd)"| 引号类型 | 语法规则 | 变量解析 | 命令执行 | 示例 |
|---|---|---|---|---|
| 双引号 | 弱引用 | 解析变量,替换为变量值 | 支持执行命令 | |
| 单引号 | 强引用 | 不解析变量,原样输出 | 不执行任何命令 | |
| 反引号 | 命令替换 | 执行引号内命令,输出结果替换自身 | 执行系统命令 | date` |
现代脚本推荐使用替代反引号,因其支持嵌套且更清晰。$()
变量是脚本的基石。除了系统预定义的环境变量(如, PWD, HOME),还有用于接收脚本参数的位置参数变量(PATH$1, $2... $@)以及用户自定义变量。
| 变量 | 含义 |
|---|---|
| 当前脚本的文件名 / 路径 | |
| 第一个传入参数 | |
| 第二个传入参数 | |
| 传入参数的总个数 | |
| 上一条命令的退出状态码:= 执行成功,非= 执行失败 | |
| 当前脚本运行的进程 ID号(PID) |
示例:若执行,则./test.sh a b c,$1=a,$2=b,$3=c。$#=3
定义自定义变量时,等号两边不能有空格:name="value"。使用变量时用$variable或${variable}。
# 定义变量
i=0
str="hello world"
# 调用变量
echo $i
echo ${str}_shell # 拼接字符串,{}区分变量边界2. 流程控制:让脚本拥有逻辑
条件判断(if语句)让脚本能够根据不同情况执行不同分支。test命令或[ ]操作符用于进行条件检查。
if [ 表达式 ]; then # 推荐简写格式,[] 两侧必须有空格
语句块
elif [ 表达式 ]; then
语句块
else
语句块
fi
if [ 条件 ]
then # 如果then换行,可以省略分号
语句
fi与test:[]等价于[ 表达式 ]。test 表达式
num=10
if [ $num -gt 5 ]; then
echo "数字大于5"
fi
# Bash支持两种语法,推荐第一种
if [[ $str == "test" ]]; then # [[ ]] 是Bash关键字,更强大
echo "匹配"
fi
# 使用(( ))进行算术比较
if (( a > b )); then
echo "a大于b"
fi| 特性 | ||
|---|---|---|
| 类型 | 条件表达式 | 算术表达式 |
| 用途 | 字符串、文件测试 | 数值计算和比较 |
| 返回值 | 逻辑真/假(0/1) | 算术结果(数值) |
| 是否需要$ | 需要变量前的$ | 不需要变量前的$ |
| 示例 |
对于多值匹配,`case`语句比多个`if-elif`更简洁清晰。
case 变量值 in
9)
语句块
;; # 每个分支必须以双分号结尾
8)
语句块
;;
*) # 通配符,匹配所有未命中的情况(默认分支)
语句块
;;
esac # case的结束标记,是case的反写它支持通配符,例如可以匹配多个值。9|8|7) 语句块 ;;
3. 循环:处理重复任务
`for`循环常用于遍历一个已知的列表或数字范围。
# 遍历字符串/文件列表
for var in 1 2 3 4 5
do
echo "数值:$var"
donefor ((i=0; i<5; i++))
do
echo $i
done`while`循环在条件为真时持续执行,适用于循环次数未知的场景(如读取文件直到末尾)。
i=1
while [ $i -le 5 ]
do
echo $i
i=$((i+1)) # 数值自增运算
done`until`循环则与`while`逻辑相反,条件为假时执行。
i=1
until [ $i -gt 5 ]
do
echo $i
i=$((i+1))
done在循环中,可以使用跳出整个循环,或用break跳过本次循环的剩余部分。continue
4. 数组、函数与计算
Shell支持一维数组,用于存储一组相关的值。
# 方式1:直接赋值
arr=("apple" "banana" "orange")
# 方式2:指定下标赋值
arr[0]="red"
arr[1]="blue"
echo ${arr[0]} # 获取单个元素
echo ${arr[*]} # 获取所有元素
echo ${#arr[*]} # 获取数组长度函数用于封装可复用的代码块,使脚本结构更清晰。
# 标准格式
function 函数名() {
语句块
# return 数字:设置函数退出状态码(0-255)
}
# 简化写法(省略function关键字,更常用)
函数名() {
echo "执行函数:$1" # 函数内 $1 接收第一个参数
}# 调用函数,直接写函数名,后接参数
print_info "hello" "shell"
# 函数内获取参数:$1 $2 $# 规则与脚本位置参数一致# 方式1:通过echo输出结果,外部用$()接收
add() {
echo $(( $1 + $2 ))
}
res=$(add 1 2)
echo "计算结果:$res"对于数学运算和字符串操作,可以使用`expr`命令。主要用于整数运算。expr
# 整数运算(注意:运算符两侧必须有空格)
expr 10 + 5 # 输出: 15
expr 20 - 3 # 输出: 17
expr 6 \* 3 # 输出: 18(*需要转义)
expr 15 / 4 # 输出: 3(整数除法)
expr 15 % 4 # 输出: 3(取模)
# 字符串长度
expr length "hello" # 输出: 5
# 子串查找
expr index "hello" "l" # 输出: 3(第一个'l'的位置)
# 子串提取
expr substr "hello" 2 3 # 输出: ell(从第2位开始取3个字符)# expr的现代替代
# 算术运算 → $(( ))
echo $((10 + 5)) # 15
echo $((20 * 3)) # 60(不需要转义)
# 字符串长度 → ${#var}
str="hello"
echo ${#str} # 5
# 子串提取 → ${str:start:length}
echo ${str:1:3} # ell要生成一个数字序列,可以使用`seq`命令,这在循环中非常有用。
# 生成1到5
seq 5
# 输出:
# 1
# 2
# 3
# 4
# 5
# 指定范围
seq 3 7
# 输出:
# 3
# 4
# 5
# 6
# 7
# 指定步长
seq 1 2 10
# 输出:
# 1
# 3
# 5
# 7
# 9
# 反向序列
seq 10 -2 1
# 输出:
# 10
# 8
# 6
# 4
# 2# 批量创建目录
for i in $(seq 1 10); do
mkdir "day$i"
done现代Bash中,也可以直接使用序列表达式作为替代:
# Bash的brace expansion(简单序列)
echo {1..5} # 1 2 3 4 5
echo {1..10..2} # 1 3 5 7 9
echo {10..1..-2} # 10 8 6 4 2
# for循环替代
for i in {1..5}; do
echo $i
done
# 使用C语言风格的for循环
for ((i=1; i<=5; i++)); do
echo $i
done四、总结与展望
通过本文的梳理,我们从Linux操作系统与Shell的基本概念出发,系统学习了核心的Shell命令及其高效组合技巧,并初步掌握了Shell脚本编程的逻辑结构与核心语法。Shell的强大之处在于其直接、高效和强大的自动化能力。无论是管理服务器、处理日志文件,还是构建复杂的数据处理流水线,熟练运用Shell都能让你事半功倍。
将Shell脚本与更高级的编程语言(如Python)结合,可以构建出极其强大的自动化工具链。例如,你可以用Shell脚本监控GPU状态、自动调度机器学习训练任务、抓取和预处理用于自然语言处理(NLP)的语料数据,然后用Python的深度学习框架(如TensorFlow或PyTorch)构建神经网络模型。这种组合充分发挥了Shell在系统层操作的高效性和Python在科学计算与AI建模领域的丰富生态。[AFFILIATE_SLOT_2]
记住,学习Shell的最佳方式就是“在终端中学习”。多动手实践,将常用操作脚本化,你很快就能感受到自动化带来的自由与效率提升。从系统管理到AI工程化,扎实的Shell功底都将是你技术工具箱中一把锋利而可靠的瑞士军刀。
>>>*ls *.txt?ls file?.txt[]ls file[123].txt[^]ls file[^0-9].txtrwx-c-x-v-f-zgzip.tar.gz.tgz-jbzip2.tar.bz2.tbz" "$()echo "当前目录:$PWD"' 'echo '输出纯文本 $PWD'` `echo 当前时间:`$0$1$2$#$?00$$[[ ]](( ))[[ $str == "test" ]](( a > b ))
浙公网安备 33010602011771号