终端与Shell

终端和Shell是Linux系统的核心工具。理解它们的工作原理,掌握基本操作,是成为Linux高手的必经之路。本章将深入讲解终端与Shell的关系、Bash Shell的使用技巧以及Shell编程基础。


一、终端与Shell概述

1.1 终端(Terminal)

1.1.1 什么是终端

终端是用户与Linux系统交互的界面设备。

历史演变

早期(1960-1970年代):
- 物理终端:电传打字机(TTY)
- 字符终端:DEC VT100等

现代(1990年代至今):
- 终端模拟器:GNOME Terminal、Konsole、xterm
- 虚拟终端:Ctrl+Alt+F1~F6

东巴文观点:终端就像电话机,Shell就像电话接线员,您通过终端(电话机)与Shell(接线员)对话,Shell再帮您连接到Linux内核。

1.1.2 终端模拟器

常见终端模拟器

终端名称 桌面环境 特点
GNOME Terminal GNOME Ubuntu默认,功能完善
Konsole KDE KDE默认,功能强大
XFCE Terminal XFCE 轻量级,XFCE默认
xterm 通用 最基础的终端模拟器
Terminator 通用 支持分屏
Tilix 通用 平铺式终端

打开终端

# Ubuntu/Debian(GNOME)
Ctrl + Alt + T

# 或在活动视图搜索"终端"

# CentOS/RHEL
应用程序 → 系统 → 终端

# 虚拟终端(所有发行版)
Ctrl + Alt + F2~F6  # 切换到虚拟终端
Ctrl + Alt + F1     # 返回图形界面

1.2 Shell

1.2.1 什么是Shell

Shell是命令行解释器,负责接收用户命令并传递给内核执行。

Shell的作用

用户输入命令 → Shell解释命令 → 内核执行 → 返回结果 → Shell显示结果

东巴文比喻:Shell就像翻译官,把您说的"人话"(命令)翻译成内核能听懂的"机器语言"。

1.2.2 Shell类型

常见Shell类型

Shell 说明 路径
Bash 最常用的Shell,GNU项目 /bin/bash
Sh Bourne Shell,Unix原始Shell /bin/sh
Zsh 功能强大,高度可定制 /bin/zsh
Dash 轻量级,Debian默认 /bin/dash
Csh C Shell,语法类似C语言 /bin/csh
Ksh Korn Shell,功能强大 /bin/ksh

查看当前Shell

# 查看当前使用的Shell
echo $SHELL

# 输出示例:
# /bin/bash

# 查看系统支持的所有Shell
cat /etc/shells

# 输出示例:
# /bin/sh
# /bin/bash
# /usr/bin/bash
# /bin/rbash
# /usr/bin/rbash
# /bin/dash
# /usr/bin/dash

切换Shell

# 临时切换到其他Shell
zsh        # 切换到Zsh
exit       # 退出Zsh,返回Bash

# 永久切换默认Shell
chsh -s /bin/zsh

# 需要重新登录才能生效

东巴文提示:Bash是最常用的Shell,本章重点讲解Bash。


二、Bash Shell基础

2.1 Bash提示符

2.1.1 提示符格式

标准提示符

[用户名@主机名 当前目录]用户类型提示符

示例

# 普通用户
dbw@ubuntu:~$

# root用户
root@ubuntu:~#

# 具体目录
dbw@ubuntu:/etc$

提示符符号说明

符号 说明
$ 普通用户提示符
# root用户提示符
~ 用户主目录
- 上一次所在目录

2.1.2 自定义提示符

PS1变量

# 查看当前PS1设置
echo $PS1

# 输出示例:
# \[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\u@\h:\w\$

# 临时修改提示符
PS1="[\u@\h \W]\\$ "

# 提示符转义字符
\u  # 用户名
\h  # 主机名(短)
\H  # 主机名(完整)
\w  # 当前目录(完整路径)
\W  # 当前目录(仅目录名)
\d  # 日期
\t  # 时间(24小时制)
\T  # 时间(12小时制)
\$  # 用户类型提示符($或#)

彩色提示符

# 设置彩色提示符
PS1="\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ "

# 颜色代码:
# 30: 黑色  31: 红色  32: 绿色  33: 黄色
# 34: 蓝色  35: 紫色  36: 青色  37: 白色
# 01: 加粗  00: 默认

东巴文提示:将PS1设置写入~/.bashrc文件可永久生效。

2.2 Bash快捷键

2.2.1 光标移动

快捷键 功能
Ctrl + A 移动到行首
Ctrl + E 移动到行尾
Ctrl + B 向左移动一个字符
Ctrl + F 向右移动一个字符
Alt + B 向左移动一个单词
Alt + F 向右移动一个单词

2.2.2 编辑操作

快捷键 功能
Ctrl + U 删除光标前所有内容
Ctrl + K 删除光标后所有内容
Ctrl + W 删除光标前一个单词
Ctrl + D 删除光标后一个字符(或退出终端)
Ctrl + H 删除光标前一个字符(同Backspace)
Ctrl + T 交换光标前两个字符
Alt + T 交换光标前两个单词
Alt + D 删除光标后一个单词

2.2.3 控制操作

快捷键 功能
Ctrl + C 中断当前命令
Ctrl + D 退出当前Shell
Ctrl + Z 暂停当前命令(放入后台)
Ctrl + L 清屏
Ctrl + S 暂停屏幕输出
Ctrl + Q 恢复屏幕输出

2.2.4 历史命令

快捷键 功能
Ctrl + P 上一条命令(同↑)
Ctrl + N 下一条命令(同↓)
Ctrl + R 搜索历史命令
Alt + . 使用上一条命令的最后一个参数
!! 执行上一条命令
!n 执行第n条历史命令
!字符串 执行最近以"字符串"开头的命令

历史命令示例

# 查看历史命令
history

# 输出示例:
# 1001  ls -la
# 1002  cd /etc
# 1003  cat passwd

# 执行第1002条命令
!1002

# 执行上一条命令
!!

# 执行最近以ls开头的命令
!ls

# 搜索历史命令
Ctrl + R
# 输入关键词,按Enter执行

2.2.5 Tab补全

文件名补全

# 输入部分文件名,按Tab键
cd /ho<Tab>      # 自动补全为 cd /home/
ls /etc/pass<Tab>  # 自动补全为 ls /etc/passwd

# 双击Tab显示所有匹配项
cd /etc/<Tab><Tab>

命令补全

# 输入命令开头,按Tab键
sys<Tab>  # 显示所有以sys开头的命令

东巴文提示:Tab补全是Linux终端最常用的功能,能大幅提高输入效率。

2.3 命令别名

2.3.1 定义别名

alias命令

# 查看所有别名
alias

# 定义别名
alias ll='ls -lh'
alias la='ls -A'
alias l='ls -CF'
alias cls='clear'

# 使用别名
ll        # 等同于 ls -lh
la        # 等同于 ls -A

2.3.2 删除别名

# 删除别名
unalias ll

# 删除所有别名
unalias -a

2.3.3 永久别名

编辑配置文件

# 编辑~/.bashrc文件
vim ~/.bashrc

# 在文件末尾添加
alias ll='ls -lh'
alias la='ls -A'
alias l='ls -CF'
alias cls='clear'
alias grep='grep --color=auto'
alias ..='cd ..'
alias ...='cd ../..'

# 保存退出后,重新加载配置
source ~/.bashrc

东巴文最佳实践:常用别名应写入~/.bashrc,避免每次重新定义。


三、Shell变量

3.1 变量基础

3.1.1 变量定义

定义变量

# 定义变量(等号两边不能有空格)
变量名=值

# 示例
name="东巴文"
age=18
score=95.5

# 使用变量($变量名 或 ${变量名})
echo $name
echo ${name}

# 输出:
# 东巴文
# 东巴文

变量命名规则

1. 只能包含字母、数字、下划线
2. 不能以数字开头
3. 区分大小写
4. 不能使用Shell关键字

正确示例

name="张三"
_name="李四"
NAME="王五"
age=20

错误示例

2name="张三"     # 错误:以数字开头
my-name="李四"   # 错误:包含连字符

3.1.2 变量类型

Shell变量类型

类型 说明 示例
局部变量 仅在当前Shell有效 name="张三"
环境变量 在所有子进程中有效 export PATH
只读变量 不能修改或删除 readonly name

局部变量

# 定义局部变量
name="东巴文"

# 使用变量
echo $name

# 删除变量
unset name

# 验证删除
echo $name  # 无输出

只读变量

# 定义只读变量
readonly name="东巴文"

# 尝试修改(会报错)
name="张三"
# bash: name: 只读变量

# 尝试删除(会报错)
unset name
# bash: name: 只读变量

3.2 环境变量

3.2.1 常见环境变量

系统环境变量

变量名 说明 示例
PATH 命令搜索路径 /usr/bin:/bin
HOME 用户主目录 /home/dbw
USER 当前用户名 dbw
SHELL 当前Shell /bin/bash
PWD 当前目录 /home/dbw
LANG 系统语言 zh_CN.UTF-8
TERM 终端类型 xterm-256color
PS1 命令提示符 \u@\h:\w$
HISTSIZE 历史命令数量 1000

查看环境变量

# 查看所有环境变量
env
# 或
printenv

# 查看单个环境变量
echo $PATH
echo $HOME
echo $USER

# 查看所有变量(包括局部变量)
set

3.2.2 设置环境变量

export命令

# 设置环境变量
export MY_VAR="东巴文"

# 查看环境变量
echo $MY_VAR

# 在子进程中使用
bash
echo $MY_VAR  # 仍然有效
exit

# 追加环境变量
export PATH=$PATH:/opt/myapp/bin

东巴文提示:export设置的环境变量仅在当前Shell及其子进程中有效,重启后失效。

3.2.3 永久环境变量

修改配置文件

# 用户级配置文件
vim ~/.bashrc

# 添加环境变量
export MY_VAR="东巴文"
export PATH=$PATH:/opt/myapp/bin

# 保存退出后,重新加载
source ~/.bashrc

系统级配置文件

# 系统级配置文件(需要root权限)
sudo vim /etc/environment

# 添加环境变量
MY_VAR="东巴文"

# 或编辑/etc/profile
sudo vim /etc/profile

# 添加
export MY_VAR="东巴文"

配置文件加载顺序

登录Shell:
1. /etc/profile
2. ~/.bash_profile
3. ~/.bash_login
4. ~/.profile

非登录Shell:
1. ~/.bashrc

东巴文建议:用户级环境变量建议写入~/.bashrc,系统级环境变量写入/etc/profile

3.3 特殊变量

3.3.1 位置参数

位置参数变量

变量 说明
$0 脚本名称
1 1~9 第1~9个参数
${10} 第10个参数(需要花括号)
$# 参数个数
$* 所有参数(作为单个字符串)
$@ 所有参数(作为独立字符串)
$? 上一个命令的退出状态
$$ 当前进程PID
$! 后台运行的最后一个进程PID

示例脚本

#!/bin/bash
# 文件名:test.sh

echo "脚本名称:$0"
echo "第一个参数:$1"
echo "第二个参数:$2"
echo "参数个数:$#"
echo "所有参数:$*"
echo "所有参数:$@"
echo "上一个命令退出状态:$?"
echo "当前进程PID:$$"

执行脚本

chmod +x test.sh
./test.sh a b c d

# 输出:
# 脚本名称:./test.sh
# 第一个参数:a
# 第二个参数:b
# 参数个数:4
# 所有参数:a b c d
# 所有参数:a b c d
# 上一个命令退出状态:0
# 当前进程PID:12345

3.3.2 特殊符号

引号

# 双引号:保留变量和命令替换
name="东巴文"
echo "欢迎 $name"
# 输出:欢迎 东巴文

# 单引号:原样输出
echo '欢迎 $name'
# 输出:欢迎 $name

# 反引号或$():命令替换
echo "当前目录:`pwd`"
echo "当前目录:$(pwd)"
# 输出:当前目录:/home/dbw

转义字符

# 反斜杠转义
echo "价格:\$100"
# 输出:价格:$100

echo "换行\n制表\t"
# 输出:换行\n制表\t(默认不解释)

# 使用-e选项解释转义字符
echo -e "换行\n制表\t"
# 输出:
# 换行
# 制表    

四、Shell配置文件

4.1 配置文件类型

4.1.1 系统级配置文件

文件 说明
/etc/profile 全局登录Shell配置
/etc/bash.bashrc 全局非登录Shell配置
/etc/environment 系统环境变量

4.1.2 用户级配置文件

文件 说明
~/.bash_profile 用户登录Shell配置
~/.bash_login 用户登录Shell配置(备选)
~/.profile 用户登录Shell配置(备选)
~/.bashrc 用户非登录Shell配置
~/.bash_logout 用户退出Shell配置

4.2 配置文件加载顺序

4.2.1 登录Shell

加载顺序

1. /etc/profile
2. ~/.bash_profile(如果存在)
   或 ~/.bash_login(如果存在)
   或 ~/.profile
3. ~/.bashrc(通常在~/.bash_profile中调用)

~/.bash_profile示例

# ~/.bash_profile

# 加载~/.bashrc
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

# 设置PATH
export PATH=$PATH:$HOME/bin

# 设置环境变量
export MY_VAR="东巴文"

4.2.2 非登录Shell

加载顺序

1. /etc/bash.bashrc
2. ~/.bashrc

~/.bashrc示例

# ~/.bashrc

# 别名定义
alias ll='ls -lh'
alias la='ls -A'
alias l='ls -CF'
alias cls='clear'

# 环境变量
export PATH=$PATH:/opt/myapp/bin

# 提示符设置
PS1='\u@\h:\w\$ '

# 自定义函数
mkcd() {
    mkdir -p "$1"
    cd "$1"
}

4.3 配置文件最佳实践

4.3.1 组织配置文件

推荐结构

# ~/.bashrc

# ==================== 别名定义 ====================
alias ll='ls -lh'
alias la='ls -A'
alias l='ls -CF'
alias cls='clear'
alias grep='grep --color=auto'

# ==================== 环境变量 ====================
export PATH=$PATH:$HOME/bin:/opt/myapp/bin
export EDITOR=vim
export LANG=zh_CN.UTF-8

# ==================== 提示符设置 ====================
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

# ==================== 自定义函数 ====================
# 创建目录并进入
mkcd() {
    mkdir -p "$1"
    cd "$1"
}

# 快速备份
backup() {
    cp "$1" "$1.backup.$(date +%Y%m%d%H%M%S)"
}

# ==================== 其他设置 ====================
# 历史命令设置
export HISTSIZE=10000
export HISTFILESIZE=20000
export HISTCONTROL=ignoreboth

# 忽略大小写
bind 'set completion-ignore-case on'

# 东巴文提示:将配置分类组织,便于维护

4.3.2 重新加载配置

# 重新加载~/.bashrc
source ~/.bashrc
# 或
. ~/.bashrc

# 重新加载~/.bash_profile
source ~/.bash_profile

东巴文提示:修改配置文件后,需要重新加载才能生效。


五、Shell脚本基础

5.1 第一个Shell脚本

5.1.1 创建脚本

创建脚本文件

# 创建脚本文件
vim hello.sh

脚本内容

#!/bin/bash
# 第一个Shell脚本
# 作者:东巴文

echo "Hello, World!"
echo "欢迎学习Linux!"
echo "当前用户:$USER"
echo "当前目录:$PWD"

脚本说明

#!/bin/bash  # Shebang,指定解释器
# 注释       # 以#开头的行为注释
echo "..."   # 输出命令

5.1.2 执行脚本

赋予执行权限

chmod +x hello.sh

执行脚本

# 方式1:作为可执行文件
./hello.sh

# 方式2:指定解释器
bash hello.sh

# 方式3:使用source(在当前Shell执行)
source hello.sh
# 或
. hello.sh

东巴文提示:推荐使用方式1,脚本需要有执行权限。

5.2 输入输出

5.2.1 输出命令

echo命令

# 基本输出
echo "Hello, World!"

# 输出变量
name="东巴文"
echo "欢迎 $name"

# 不换行输出
echo -n "不换行"
echo "输出"

# 解释转义字符
echo -e "第一行\n第二行"

printf命令

# 格式化输出
printf "姓名:%s,年龄:%d\n" "张三" 20

# 输出:
# 姓名:张三,年龄:20

# 格式说明符:
# %s  字符串
# %d  整数
# %f  浮点数
# %x  十六进制
# \n  换行
# \t  制表符

5.2.2 输入命令

read命令

# 基本输入
echo "请输入您的姓名:"
read name
echo "欢迎您,$name!"

# 带提示的输入
read -p "请输入您的年龄:" age
echo "您的年龄是:$age"

# 输入密码(不显示)
read -s -p "请输入密码:" password
echo
echo "密码已接收"

# 限时输入(5秒)
read -t 5 -p "请在5秒内输入:" input

# 限制输入字符数(3个字符)
read -n 3 -p "请输入3个字符:" chars
echo
echo "您输入了:$chars"

5.3 条件判断

5.3.1 if语句

基本语法

if [ 条件 ]; then
    命令
fi

# 或
if [ 条件 ]
then
    命令
fi

示例

#!/bin/bash

age=18

if [ $age -ge 18 ]; then
    echo "成年人"
fi

if-else语句

#!/bin/bash

read -p "请输入您的年龄:" age

if [ $age -ge 18 ]; then
    echo "成年人"
else
    echo "未成年人"
fi

if-elif-else语句

#!/bin/bash

read -p "请输入您的分数:" score

if [ $score -ge 90 ]; then
    echo "优秀"
elif [ $score -ge 80 ]; then
    echo "良好"
elif [ $score -ge 60 ]; then
    echo "及格"
else
    echo "不及格"
fi

5.3.2 条件测试

数值比较

操作符 说明 示例
-eq 等于 [ aeqa -eq b ]
-ne 不等于 [ anea -ne b ]
-gt 大于 [ agta -gt b ]
-lt 小于 [ alta -lt b ]
-ge 大于等于 [ agea -ge b ]
-le 小于等于 [ alea -le b ]

字符串比较

操作符 说明 示例
= 等于 [ "a"="a" = "b" ]
!= 不等于 [ "a"!="a" != "b" ]
-z 字符串为空 [ -z "$a" ]
-n 字符串非空 [ -n "$a" ]

文件测试

操作符 说明 示例
-e 文件存在 [ -e file ]
-f 是普通文件 [ -f file ]
-d 是目录 [ -d dir ]
-r 可读 [ -r file ]
-w 可写 [ -w file ]
-x 可执行 [ -x file ]
-s 文件非空 [ -s file ]

逻辑运算

# 逻辑与
if [ $age -ge 18 ] && [ $age -le 60 ]; then
    echo "工作年龄"
fi

# 逻辑或
if [ $score -lt 60 ] || [ $score -gt 100 ]; then
    echo "分数异常"
fi

# 逻辑非
if [ ! -f "$file" ]; then
    echo "文件不存在"
fi

5.4 循环

5.4.1 for循环

基本语法

# 语法1:列表循环
for 变量 in 列表
do
    命令
done

# 语法2:C风格循环
for (( 初始化; 条件; 更新 ))
do
    命令
done

示例

#!/bin/bash

# 列表循环
echo "遍历列表:"
for name in 张三 李四 王五
do
    echo "姓名:$name"
done

# 遍历文件
echo "遍历当前目录的文件:"
for file in *.txt
do
    echo "文件:$file"
done

# C风格循环
echo "数字1到5:"
for (( i=1; i<=5; i++ ))
do
    echo "数字:$i"
done

5.4.2 while循环

基本语法

while [ 条件 ]
do
    命令
done

示例

#!/bin/bash

# 基本while循环
count=1
while [ $count -le 5 ]
do
    echo "计数:$count"
    count=$((count + 1))
done

# 读取文件
echo "读取文件内容:"
while read line
do
    echo "行:$line"
done < /etc/passwd

5.4.3 until循环

基本语法

until [ 条件 ]
do
    命令
done

示例

#!/bin/bash

# until循环(条件为假时执行)
count=1
until [ $count -gt 5 ]
do
    echo "计数:$count"
    count=$((count + 1))
done

东巴文提示:until循环与while循环相反,条件为假时执行循环体。

5.4.4 循环控制

break和continue

#!/bin/bash

# break示例:跳出循环
for i in {1..10}
do
    if [ $i -eq 5 ]; then
        echo "遇到5,跳出循环"
        break
    fi
    echo "数字:$i"
done

# continue示例:跳过本次循环
echo "跳过偶数:"
for i in {1..10}
do
    if [ $((i % 2)) -eq 0 ]; then
        continue
    fi
    echo "奇数:$i"
done

六、本章小结

6.1 核心要点

✅ 终端是用户界面,Shell是命令解释器 ✅ Bash是最常用的Shell,掌握其快捷键和别名 ✅ 理解变量、环境变量和特殊变量的区别 ✅ 熟悉Shell配置文件的加载顺序 ✅ 掌握Shell脚本的基本语法

6.2 验证清单

完成本章学习后,请确认您能够:

  • 理解终端与Shell的关系
  • 使用Bash快捷键提高效率
  • 定义和使用Shell变量
  • 设置环境变量
  • 编写简单的Shell脚本
  • 使用条件判断和循环

东巴文(db-w.cn) - 让Linux学习更简单