终端和Shell是Linux系统的核心工具。理解它们的工作原理,掌握基本操作,是成为Linux高手的必经之路。本章将深入讲解终端与Shell的关系、Bash Shell的使用技巧以及Shell编程基础。
终端是用户与Linux系统交互的界面设备。
历史演变:
早期(1960-1970年代):
- 物理终端:电传打字机(TTY)
- 字符终端:DEC VT100等
现代(1990年代至今):
- 终端模拟器:GNOME Terminal、Konsole、xterm
- 虚拟终端:Ctrl+Alt+F1~F6
东巴文观点:终端就像电话机,Shell就像电话接线员,您通过终端(电话机)与Shell(接线员)对话,Shell再帮您连接到Linux内核。
常见终端模拟器:
| 终端名称 | 桌面环境 | 特点 |
|---|---|---|
| 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 # 返回图形界面
Shell是命令行解释器,负责接收用户命令并传递给内核执行。
Shell的作用:
用户输入命令 → Shell解释命令 → 内核执行 → 返回结果 → Shell显示结果
东巴文比喻: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。
标准提示符:
[用户名@主机名 当前目录]用户类型提示符
示例:
# 普通用户
dbw@ubuntu:~$
# root用户
root@ubuntu:~#
# 具体目录
dbw@ubuntu:/etc$
提示符符号说明:
| 符号 | 说明 |
|---|---|
| $ | 普通用户提示符 |
| # | root用户提示符 |
| ~ | 用户主目录 |
| - | 上一次所在目录 |
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文件可永久生效。
| 快捷键 | 功能 |
|---|---|
| Ctrl + A | 移动到行首 |
| Ctrl + E | 移动到行尾 |
| Ctrl + B | 向左移动一个字符 |
| Ctrl + F | 向右移动一个字符 |
| Alt + B | 向左移动一个单词 |
| Alt + F | 向右移动一个单词 |
| 快捷键 | 功能 |
|---|---|
| Ctrl + U | 删除光标前所有内容 |
| Ctrl + K | 删除光标后所有内容 |
| Ctrl + W | 删除光标前一个单词 |
| Ctrl + D | 删除光标后一个字符(或退出终端) |
| Ctrl + H | 删除光标前一个字符(同Backspace) |
| Ctrl + T | 交换光标前两个字符 |
| Alt + T | 交换光标前两个单词 |
| Alt + D | 删除光标后一个单词 |
| 快捷键 | 功能 |
|---|---|
| Ctrl + C | 中断当前命令 |
| Ctrl + D | 退出当前Shell |
| Ctrl + Z | 暂停当前命令(放入后台) |
| Ctrl + L | 清屏 |
| Ctrl + S | 暂停屏幕输出 |
| Ctrl + Q | 恢复屏幕输出 |
| 快捷键 | 功能 |
|---|---|
| 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执行
文件名补全:
# 输入部分文件名,按Tab键
cd /ho<Tab> # 自动补全为 cd /home/
ls /etc/pass<Tab> # 自动补全为 ls /etc/passwd
# 双击Tab显示所有匹配项
cd /etc/<Tab><Tab>
命令补全:
# 输入命令开头,按Tab键
sys<Tab> # 显示所有以sys开头的命令
东巴文提示:Tab补全是Linux终端最常用的功能,能大幅提高输入效率。
alias命令:
# 查看所有别名
alias
# 定义别名
alias ll='ls -lh'
alias la='ls -A'
alias l='ls -CF'
alias cls='clear'
# 使用别名
ll # 等同于 ls -lh
la # 等同于 ls -A
# 删除别名
unalias ll
# 删除所有别名
unalias -a
编辑配置文件:
# 编辑~/.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,避免每次重新定义。
定义变量:
# 定义变量(等号两边不能有空格)
变量名=值
# 示例
name="东巴文"
age=18
score=95.5
# 使用变量($变量名 或 ${变量名})
echo $name
echo ${name}
# 输出:
# 东巴文
# 东巴文
变量命名规则:
1. 只能包含字母、数字、下划线
2. 不能以数字开头
3. 区分大小写
4. 不能使用Shell关键字
正确示例:
name="张三"
_name="李四"
NAME="王五"
age=20
错误示例:
2name="张三" # 错误:以数字开头
my-name="李四" # 错误:包含连字符
Shell变量类型:
| 类型 | 说明 | 示例 |
|---|---|---|
| 局部变量 | 仅在当前Shell有效 | name="张三" |
| 环境变量 | 在所有子进程中有效 | export PATH |
| 只读变量 | 不能修改或删除 | readonly name |
局部变量:
# 定义局部变量
name="东巴文"
# 使用变量
echo $name
# 删除变量
unset name
# 验证删除
echo $name # 无输出
只读变量:
# 定义只读变量
readonly name="东巴文"
# 尝试修改(会报错)
name="张三"
# bash: name: 只读变量
# 尝试删除(会报错)
unset name
# bash: name: 只读变量
系统环境变量:
| 变量名 | 说明 | 示例 |
|---|---|---|
| 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
export命令:
# 设置环境变量
export MY_VAR="东巴文"
# 查看环境变量
echo $MY_VAR
# 在子进程中使用
bash
echo $MY_VAR # 仍然有效
exit
# 追加环境变量
export PATH=$PATH:/opt/myapp/bin
东巴文提示:export设置的环境变量仅在当前Shell及其子进程中有效,重启后失效。
修改配置文件:
# 用户级配置文件
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。
位置参数变量:
| 变量 | 说明 |
|---|---|
| $0 | 脚本名称 |
| 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
引号:
# 双引号:保留变量和命令替换
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"
# 输出:
# 换行
# 制表
| 文件 | 说明 |
|---|---|
| /etc/profile | 全局登录Shell配置 |
| /etc/bash.bashrc | 全局非登录Shell配置 |
| /etc/environment | 系统环境变量 |
| 文件 | 说明 |
|---|---|
| ~/.bash_profile | 用户登录Shell配置 |
| ~/.bash_login | 用户登录Shell配置(备选) |
| ~/.profile | 用户登录Shell配置(备选) |
| ~/.bashrc | 用户非登录Shell配置 |
| ~/.bash_logout | 用户退出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="东巴文"
加载顺序:
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"
}
推荐结构:
# ~/.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'
# 东巴文提示:将配置分类组织,便于维护
# 重新加载~/.bashrc
source ~/.bashrc
# 或
. ~/.bashrc
# 重新加载~/.bash_profile
source ~/.bash_profile
东巴文提示:修改配置文件后,需要重新加载才能生效。
创建脚本文件:
# 创建脚本文件
vim hello.sh
脚本内容:
#!/bin/bash
# 第一个Shell脚本
# 作者:东巴文
echo "Hello, World!"
echo "欢迎学习Linux!"
echo "当前用户:$USER"
echo "当前目录:$PWD"
脚本说明:
#!/bin/bash # Shebang,指定解释器
# 注释 # 以#开头的行为注释
echo "..." # 输出命令
赋予执行权限:
chmod +x hello.sh
执行脚本:
# 方式1:作为可执行文件
./hello.sh
# 方式2:指定解释器
bash hello.sh
# 方式3:使用source(在当前Shell执行)
source hello.sh
# 或
. hello.sh
东巴文提示:推荐使用方式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 制表符
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"
基本语法:
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
数值比较:
| 操作符 | 说明 | 示例 |
|---|---|---|
| -eq | 等于 | [ b ] |
| -ne | 不等于 | [ b ] |
| -gt | 大于 | [ b ] |
| -lt | 小于 | [ b ] |
| -ge | 大于等于 | [ b ] |
| -le | 小于等于 | [ b ] |
字符串比较:
| 操作符 | 说明 | 示例 |
|---|---|---|
| = | 等于 | [ "b" ] |
| != | 不等于 | [ "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
基本语法:
# 语法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
基本语法:
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
基本语法:
until [ 条件 ]
do
命令
done
示例:
#!/bin/bash
# until循环(条件为假时执行)
count=1
until [ $count -gt 5 ]
do
echo "计数:$count"
count=$((count + 1))
done
东巴文提示:until循环与while循环相反,条件为假时执行循环体。
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
✅ 终端是用户界面,Shell是命令解释器 ✅ Bash是最常用的Shell,掌握其快捷键和别名 ✅ 理解变量、环境变量和特殊变量的区别 ✅ 熟悉Shell配置文件的加载顺序 ✅ 掌握Shell脚本的基本语法
完成本章学习后,请确认您能够:
东巴文(db-w.cn) - 让Linux学习更简单