Linux 的 Shell 详解:从入门到上手

Linux 的 Shell 详解:从入门到上手

一、什么是 Shell?

咱们可以把计算机系统比作一家复杂的餐厅:Linux 内核是后厨里掌勺的总厨师,负责处理所有硬件资源(比如 CPU、内存、硬盘)的调度和运算;而用户就是来就餐的顾客,需要通过某种方式向厨师传递需求(比如 “炒一盘菜”“盛一碗汤”)。

Shell 正是连接顾客(用户)和厨师(内核)的 “服务员”—— 它是一个命令解释器,会把用户输入的命令翻译成内核能理解的语言,内核执行完毕后,再把结果通过 Shell 反馈给用户。

举个更具体的例子:当你想查看 “/home” 目录下的文件时,输入ls /home命令,这个过程的本质是:

Shell 接收ls /home命令并解析

向内核发送 “读取 /home 目录文件列表” 的请求

内核调用文件系统模块获取数据

内核将文件列表返回给 Shell

Shell 将结果格式化后显示在终端上

除了执行单个命令,Shell 还能批量处理命令(通过脚本),甚至实现复杂的逻辑判断和循环操作,这也是它比图形界面更高效的核心原因。

二、Shell 的种类

目前常见的 Shell 有十多种,除了之前提到的 bash、sh、zsh,还有 ksh、csh、tcsh 等,它们在语法和功能上各有侧重:

Shell 类型

特点与适用场景

bash

1989 年发布,是 Bourne Shell(sh)的增强版兼容 sh 语法,新增数组、函数、命令补全等功能支持通配符(*、?)和管道组合几乎所有 Linux 发行版(Ubuntu、CentOS 等)的默认 Shell推荐新手优先掌握

sh

1979 年随 Unix 诞生的原始 Shell语法简单但功能有限(无数组、无函数)现在多作为符号链接指向 bash 或其他兼容 Shell仅在老旧系统或特定脚本中使用

zsh

1990 年发布,兼容 bash 但功能更强大支持主题美化(如 agnoster 主题)、插件扩展(通过 oh-my-zsh)智能命令补全(如目录、参数自动提示)拼写纠错(输入错误命令时自动提示)适合追求高效和个性化的进阶用户

ksh

1983 年由 AT&T 开发,融合 sh 和 csh 的优点支持脚本调试和数学运算在商业 Unix 系统(如 AIX)中较常见

csh/tcsh

语法类似 C 语言,适合编程习惯的用户tcsh 是 csh 的增强版,支持命令历史和补全因兼容性问题,现在使用较少

查看系统已安装的 Shell:

cat /etc/shells # 列出系统支持的所有Shell

切换默认 Shell(需注销后生效):

chsh -s /bin/zsh # 将默认Shell改为zsh

三、Shell 的基本命令

1. 文件与目录操作命令

ls(列出目录内容)

核心功能:显示指定目录下的文件和子目录,默认显示当前目录。

常用选项:

-a:显示所有文件(包括以.开头的隐藏文件,如.bashrc)

-l:以长格式显示(权限、所有者、大小、修改时间等)

-h:配合-l使用,以人性化单位显示大小(如 K、M、G)

-t:按修改时间排序(最新的在前面)

-r:反向排序(如配合-t实现按时间倒序)

-d:仅显示目录本身(而非目录内内容)

示例:

ls -la ~ # 显示主目录下所有文件(包括隐藏)的详细信息

ls -lht /var/log # 以人性化单位显示/var/log目录下文件,按修改时间排序

ls -d /etc/*conf # 显示/etc目录下所有以conf结尾的目录(而非内容)

cd(切换目录)

核心功能:切换当前工作目录,路径可以是绝对路径(从/开始)或相对路径(相对于当前目录)。

特殊用法:

cd 或 cd ~:切换到当前用户的主目录(如/home/yourname)

cd ..:切换到上一级目录

cd -:切换到上一次所在的目录

cd ./docs:切换到当前目录下的 docs 子目录(./可省略)

cd /usr/local:切换到绝对路径/usr/local

示例:

cd ~/Downloads # 进入主目录下的Downloads文件夹

cd ../pictures # 进入上一级目录下的pictures文件夹

cd - # 在两个目录间快速切换

pwd(显示当前目录)

核心功能:打印当前工作目录的绝对路径,避免 “迷路”。

示例:

pwd # 输出:/home/yourname/work/project

mkdir(创建目录)

核心功能:创建新目录,支持一次性创建多级目录。

常用选项:

-p:递归创建目录(父目录不存在时自动创建)

示例:

mkdir blog # 创建名为blog的目录

mkdir -p blog/{posts,images} # 同时创建blog目录及其中的posts和images子目录

rmdir(删除空目录)

核心功能:仅删除空目录,若目录非空会报错。

示例:

rmdir empty_folder # 删除空目录empty_folder

rm(删除文件 / 目录)

核心功能:删除文件或目录(需谨慎使用,删除后难以恢复)。

常用选项:

-f:强制删除(不提示确认)

-r:递归删除目录及其中所有内容

-i:删除前提示确认

示例:

rm old.txt # 删除文件old.txt(会提示确认)

rm -f temp.log # 强制删除temp.log(不提示)

rm -rf old_dir # 递归删除old_dir目录及所有内容(危险操作!)

cp(复制文件 / 目录)

核心功能:复制文件或目录到指定位置。

常用选项:

-i:目标文件存在时提示是否覆盖

-r:递归复制目录(必须用于目录复制)

-v:显示复制过程

示例:

cp note.txt backup/ # 复制note.txt到backup目录

cp -i report.pdf ~/docs/ # 复制report.pdf到主目录的docs,若存在则提示

cp -rv project/ /media/usb/ # 递归复制project目录到U盘,显示复制过程

mv(移动 / 重命名文件 / 目录)

核心功能:移动文件 / 目录到新位置,或重命名(目标位置与源位置相同则为改名)。

示例:

mv file.txt docs/ # 移动file.txt到docs目录

mv oldname.txt newname.txt # 将文件重命名为newname.txt

mv pics/ images/ # 将目录pics重命名为images

touch(创建文件 / 更新时间)

核心功能:创建空文件,或更新已有文件的访问 / 修改时间。

示例:

touch readme.md # 创建空文件readme.md

touch -d "2023-01-01" oldfile # 将oldfile的时间修改为2023年1月1日

2. 文件内容查看命令

cat(连接并显示文件内容)

核心功能:一次性显示文件所有内容,适合查看小型文件。

常用选项:

-n:显示行号

-b:仅显示非空行的行号

示例:

cat story.txt # 查看story.txt内容

cat -n config.ini # 显示config.ini内容并带行号

more/less(分页查看文件)

核心功能:分页显示大文件内容(避免内容一次性刷屏)。

more:只能向前翻页,支持空格(翻页)、Enter(换行)、q(退出)

less:更强大,支持前后翻页(PgUp/PgDn)、搜索(/ 关键词)、q(退出)

示例:

more large_log.txt # 分页查看大日志文件

less /etc/manpath.config # 用less查看配置文件,按/搜索关键词

head/tail(查看文件首尾内容)

核心功能:

head:显示文件开头部分(默认前 10 行)

tail:显示文件结尾部分(默认后 10 行)

常用选项:

-n N:指定显示 N 行(如-n 20显示 20 行)

-f:实时跟踪文件新增内容(常用于查看日志)

示例:

head -n 5 scores.csv # 查看scores.csv的前5行

tail -n 3 error.log # 查看error.log的最后3行

tail -f /var/log/syslog # 实时监控系统日志新增内容(按Ctrl+C退出)

grep(搜索文本内容)

核心功能:在文件或命令输出中搜索匹配指定模式的行。

常用选项:

-i:忽略大小写(如同时匹配 “Hello” 和 “hello”)

-n:显示匹配行的行号

-r:递归搜索目录下所有文件

-v:显示不匹配的行

--color:高亮显示匹配的内容

示例:

grep "error" app.log # 在app.log中搜索包含error的行

grep -in "warning" /var/log/* # 在/var/log下所有文件中搜索warning(忽略大小写并显示行号)

grep -rv "test" src/ # 在src目录下递归搜索不包含test的行

四、管道和重定向

1. 管道(|)

管道的本质是 “将前一个命令的标准输出作为后一个命令的标准输入”,可以串联多个命令实现复杂功能。

多层管道示例:

# 统计当前目录下所有.txt文件的总行数

ls -l *.txt | grep -v "^d" | wc -l

# 解析:

# 1. ls -l *.txt:列出所有.txt文件的详细信息

# 2. grep -v "^d":排除目录(只保留文件,^d表示以d开头的行,即目录)

# 3. wc -l:统计行数(每个文件对应一行,即文件总数)

# 查看系统中占用内存最高的前5个进程

ps aux | sort -k4nr | head -n 5

# 解析:

# 1. ps aux:显示所有进程的详细信息

# 2. sort -k4nr:按第4列(内存占用)从大到小排序(n表示数字排序,r表示反向)

# 3. head -n 5:取前5行

2. 重定向

输出重定向

>:覆盖式重定向(目标文件存在则清空原有内容)

>>:追加式重定向(目标文件存在则在末尾添加内容)

示例:

# 将当前目录结构保存到file_list.txt(覆盖原有内容)

ls -lR > file_list.txt

# 记录系统时间到日志(追加模式)

date >> system_log.txt

输入重定向(<)

将文件内容作为命令的标准输入。

示例:

# 统计words.txt中单词总数(等价于cat words.txt | wc -w)

wc -w < words.txt

# 从data.csv中读取内容作为mysql导入数据

mysql -u root -p < data.csv

错误重定向

2>:重定向标准错误输出(覆盖模式)

2>>:追加标准错误输出

2>&1:将标准错误输出合并到标准输出

示例:

# 执行命令时,将错误信息保存到error.log(不显示在终端)

sudo apt install unknown-package 2> error.log

# 将标准输出和错误都保存到all.log(常用日志记录方式)

python script.py > all.log 2>&1

# 将正确输出保存到success.log,错误输出保存到fail.log

./backup.sh > success.log 2> fail.log

五、Shell 脚本

Shell 脚本是包含一系列 Shell 命令的文本文件,通过逻辑控制实现自动化任务,扩展名通常为.sh。

1. 脚本基础要素

解释器声明:首行#!/bin/bash(指定用 bash 解释器,必须放在第一行)

注释:以#开头的行(除首行声明外),用于说明脚本功能,不被执行

命令序列:按执行顺序排列的 Shell 命令

可执行权限:需通过chmod +x script.sh赋予执行权限

2. 变量与参数

自定义变量

#!/bin/bash

# 定义变量(等号两侧不能有空格)

name="Alice"

age=30

# 使用变量(加$符号)

echo "姓名:$name"

echo "年龄:$age"

# 变量重新赋值

age=31

echo "更新后的年龄:$age"

# 命令替换(将命令输出赋值给变量,用$()或``)

current_time=$(date +"%Y-%m-%d %H:%M:%S")

echo "当前时间:$current_time"

环境变量

系统预定义的变量,用于存储系统配置信息,通常全大写。

PATH:可执行程序的搜索路径(输入命令时系统会在这些路径中查找)

HOME:当前用户的主目录

USER:当前用户名

PWD:当前工作目录(同 pwd 命令)

LANG:系统语言设置

示例:

echo $HOME # 输出:/home/yourname

echo $PATH # 输出:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin...

# 向PATH添加自定义目录(临时生效,重启终端后失效)

export PATH=$PATH:/home/yourname/scripts

# 永久生效需写入配置文件(如~/.bashrc或~/.bash_profile)

echo 'export PATH=$PATH:/home/yourname/scripts' >> ~/.bashrc

source ~/.bashrc # 立即生效(无需重启终端)

位置参数

脚本运行时传递的参数,通过$1(第一个参数)、$2(第二个参数)...$n(第 n 个参数)访问。

$0:脚本本身的文件名

$#:参数的总个数

$*:所有参数的集合(作为单个字符串)

$@:所有参数的集合(作为独立字符串)

示例(greet.sh):

#!/bin/bash

echo "脚本名:$0"

echo "参数总数:$#"

echo "第一个参数:$1"

echo "第二个参数:$2"

echo "所有参数:$@"

运行脚本:

chmod +x greet.sh

./greet.sh "Hello" "World"

# 输出:

# 脚本名:./greet.sh

# 参数总数:2

# 第一个参数:Hello

# 第二个参数:World

# 所有参数:Hello World

3. 条件判断(if 语句)

#!/bin/bash

# 判断文件是否存在

filename="data.txt"

if [ -f "$filename" ]; then

echo "$filename 是一个普通文件"

elif [ -d "$filename" ]; then

echo "$filename 是一个目录"

else

echo "$filename 不存在"

fi

# 常用判断条件:

# -f file:是否为普通文件

# -d dir:是否为目录

# -e path:路径是否存在

# -r file:是否有读权限

# -w file:是否有写权限

# -z str:字符串是否为空

# $a -eq $b:a等于b(数字比较)

# $a -gt $b:a大于b

# str1 == str2:字符串相等(注意用双等号)

4. 循环结构

for 循环

#!/bin/bash

# 批量重命名.jpg文件为编号格式(如1.jpg、2.jpg)

i=1

for file in *.jpg; do

if [ -f "$file" ]; then # 确保是文件而非目录

mv "$file" "$i.jpg"

echo "重命名 $file 为 $i.jpg"

i=$((i + 1)) # 变量自增

fi

done

while 循环

#!/bin/bash

# 倒计时脚本

count=10

while [ $count -gt 0 ]; do

echo "倒计时:$count 秒"

sleep 1 # 暂停1秒

count=$((count - 1))

done

echo "倒计时结束!"

5. 函数

#!/bin/bash

# 定义函数(计算两数之和)

add() {

local sum=$(( $1 + $2 )) # local声明局部变量

echo $sum

}

# 调用函数

result=$(add 5 3)

echo "5 + 3 = $result" # 输出:5 + 3 = 8

6. 实战脚本示例:日志分析工具

#!/bin/bash

# 功能:分析Nginx访问日志,统计访问量最高的前10个IP

# 检查日志文件是否存在

log_file="/var/log/nginx/access.log"

if [ ! -f "$log_file" ]; then

echo "错误:日志文件 $log_file 不存在"

exit 1 # 退出脚本并返回错误码1

fi

echo "正在分析日志文件:$log_file"

echo "访问量最高的前10个IP:"

# 提取IP(日志中第一列通常是IP)并统计排序

awk '{print $1}' "$log_file" | sort | uniq -c | sort -nr | head -n 10

# 解析:

# 1. awk '{print $1}':提取每行第一列(IP地址)

# 2. sort:排序IP(便于后续去重)

# 3. uniq -c:统计每个IP出现的次数(-c表示计数)

# 4. sort -nr:按次数从大到小排序

# 5. head -n 10:取前10名

运行方式:

chmod +x nginx_analysis.sh

sudo ./nginx_analysis.sh # 需root权限访问nginx日志

7. 脚本调试技巧

执行脚本时添加-x参数:bash -x script.sh(显示每一行执行的命令及参数,便于定位错误)

在关键位置添加echo命令:输出变量值或执行状态(如echo "当前处理文件:$file")

使用set -e:脚本中任何命令执行失败(返回非 0 状态)时立即退出脚本

六、Shell 高级技巧

1. 别名(alias)

为常用命令创建简写,提高效率。

# 临时生效(重启终端后失效)

alias ll='ls -lha' # 用ll代替ls -lha

alias rm='rm -i' # 让rm默认提示确认

# 永久生效(写入配置文件)

echo "alias ll='ls -lha'" >> ~/.bashrc

source ~/.bashrc # 立即生效

2. 历史命令

history:查看所有历史命令

!n:执行历史记录中第 n 条命令(如!100执行第 100 条)

!keyword:执行最近一条以 keyword 开头的命令(如!ls执行最近的 ls 命令)

Ctrl+R:反向搜索历史命令(输入关键词匹配)

3. 命令补全

按Tab键自动补全命令、文件名或目录名,按两次Tab显示所有可能的选项。

# 输入以下内容后按Tab,会自动补全为完整文件名

cat docu[Tab] # 若存在document.txt,会补全为cat document.txt

4. 快捷键

Ctrl+C:终止当前正在执行的命令

Ctrl+D:退出当前 Shell(等价于 exit 命令)

Ctrl+Z:暂停当前命令(放入后台,可用 fg 命令恢复)

Ctrl+A:光标跳到命令行开头

Ctrl+E:光标跳到命令行结尾

Ctrl+U:删除光标前的所有内容

Ctrl+K:删除光标后的所有内容

七、总结

Shell 是 Linux 系统的 “灵魂交互工具”,从简单的文件操作到复杂的自动化脚本,掌握它能极大提升工作效率。学习时建议遵循 “边学边练” 的原则:​

先熟练掌握基础命令(ls、cd、pwd、cp、mv、rm 等)理解管道和重定向的用法,学会组合命令解决问题​​逐步学习脚本编程(变量、条件、循环、函数),从简单脚本开始实践​积累实用技巧(别名、快捷键、历史命令),形成自己的高效工作流​

随着实践深入,你会发现 Shell 不仅是命令行工具,更是一种 “自动化思维” 的载体 —— 很多重复劳动都能通过几行脚本解放双手。现在就打开终端,开始你的 Shell 探索之旅吧!

相关内容

有点少😂日媒:日本上届世界杯赢球奖200万日元 冠军奖金5000万
医学科普
365体育投注备用网站

医学科普

09-15 ☯ 9056
一篇文章教会你如何做好网页设计?
365足球体育app下载

一篇文章教会你如何做好网页设计?

07-11 ☯ 3278