Skip to main content

Linux Shell 学习1️⃣ Shell 介绍和内置命令

什么是Shell​

在 Linux/UNIX 中,shell 是用户与操作系统内核 (kernel) 之间的命令解释器和交互界面。它充当了一个命令行环境,允许用户输入命令、运行程序、管理文件系统以及编写脚本来自动化任务。

1. Shell 的作用​

• 命令解释:将用户输入的命令解析并传递给操作系统执行。

• 环境管理:提供变量、路径、别名等环境配置能力。

• 进程控制:支持前台、后台进程管理,以及作业控制 (jobs, bg, fg)。

• 脚本编程:支持 if 语句、循环 (for, while)、函数等,编写 Shell 脚本自动化任务。

2. 常见的 Shell 类型​

不同的 Linux/UNIX 发行版可能默认使用不同的 Shell,以下是几种主流的 Shell:

Shell 类型说明可执行文件
Bash (Bourne Again Shell)最常见的 Shell,功能强大,支持命令补全、历史记录等/bin/bash
Sh (Bourne Shell)经典 Shell,功能较少但高效,POSIX 兼容/bin/sh
Zsh (Z Shell)兼容 Bash,支持插件系统,自定义强/bin/zsh
Ksh (Korn Shell)兼容 Sh,扩展了更多功能,如命令别名、数组等/bin/ksh
Tcsh (TENEX C Shell)C Shell 的增强版,支持 C 语言风格的语法/bin/tcsh

你可以使用 echo $SHELL 来查看当前使用的 Shell。

3. Shell 的工作流程​

当用户在终端输入命令时,Shell 的执行流程大致如下:

  1. 读取输入:等待用户输入命令。
  2. 解析命令:分析输入,包括变量替换、命令别名解析等。
  3. 查找命令:
  • 内建命令(built-in):Shell 自带的命令,如 cd, echo, export。
  • 外部命令:从 $PATH 路径查找可执行文件,如 /bin/ls。
  1. 执行命令:创建进程并运行,等待执行完成后返回结果。
  2. 返回输出:显示命令执行结果,并等待下一个输入。

4. Shell 与 Terminal 的区别​

  • Shell 是命令解释器,它解析并执行用户输入的命令。
  • Terminal (终端) 是用户与 Shell 交互的界面,如 gnome-terminal, xterm, tmux。
  • TTY/PTTY:TTY(Teletypewriter)是物理终端的抽象,而 PTTY(Pseudo Terminal)是模拟终端,如 SSH 连接时的伪终端。

你可以在终端中运行 ps -p $$ 来查看当前 Shell 进程。

abang@debian:~$ echo $SHELL
/bin/bash

abang@debian:~$ ps -p $$
PID TTY TIME CMD
165232 pts/0 00:00:00 bash

5. Shell 脚本示例​

简单的 Shell 脚本 hello.sh:

#!/bin/bash
echo "Hello, Shell!"

运行方式:

chmod +x hello.sh  # 赋予执行权限
./hello.sh # 运行脚本

Shell 是 Linux/UNIX 中不可或缺的工具,不仅提供交互式环境,还支持脚本编写,帮助用户管理系统、自动化任务。

Shell 的内置命令​

Shell 的内置命令(Built-in Commands)是由 Shell 本身直接提供的命令,而不是独立的可执行文件。内置命令执行速度快,且某些功能(如 cd)无法通过外部命令实现。

1. 如何区分内置命令和外部命令​

在 Shell 中,可以使用以下方法来判断一个命令是否是内置命令:

  • type <命令>:显示该命令的类型
  • command -v <命令>:查看命令位置
  • which <命令>:查找外部命令的路径(仅适用于外部命令)
  • help <命令>:查看 Shell 内置命令的帮助
  • man <命令>:查看命令的手册页(适用于外部命令)

示例:

$ type cd
cd is a shell builtin

$ type ls
ls is /bin/ls

上面的 cd 是内置命令,而 ls 是外部命令(存放在 /bin/ls)。

2. 常见的 Shell 内置命令​

内置命令可以分为以下几类:

(1)Shell 环境管理

命令作用
cd切换目录
pwd显示当前目录
echo输出字符串或变量值
export设置环境变量
unset删除变量
alias创建命令别名
unalias删除命令别名
set设置 Shell 选项和变量
shift移动位置参数(脚本中)
umask设置默认权限掩码
ulimit限制系统资源使用

示例:

export MY_VAR="hello"   # 设置环境变量
echo $MY_VAR # 输出变量值
unset MY_VAR # 删除变量

(2)进程管理

命令作用
jobs显示后台作业
bg将后台作业恢复为“运行”状态
fg将后台作业切换到前台
kill终止进程
wait等待进程结束
exec替换当前 Shell 进程
exit退出 Shell
logout注销当前会话
disown从作业列表中移除某个作业

示例:

sleep 60 &    # 启动后台进程
jobs # 查看作业列表
fg %1 # 让作业1回到前台
kill %1 # 终止作业1

(3)流程控制

命令作用
if ... then ... else ... fi条件判断
case ... esac多分支条件判断
for ... do ... done循环
while ... do ... done循环
until ... do ... done直到条件满足才退出
break跳出循环
continue跳过当前循环的一次迭代

示例:

if [ "$USER" = "root" ]; then
echo "你是超级用户"
else
echo "你是普通用户"
fi

(4)Shell 运行模式

命令作用
. (source)在当前 Shell 中执行脚本
source作用同 .,用于执行脚本
exec替换当前 Shell 进程

示例:

source ~/.bashrc   # 重新加载 Bash 配置

3. 内置命令的优先级​

当执行命令时,Shell 会按照以下顺序查找:

  1. 内置命令
  2. 用户定义的别名 (alias)
  3. 用户定义的函数
  4. 可执行文件(按 $PATH 路径搜索)

你可以使用 command <命令> 来强制执行外部命令,而不是 Shell 内置命令。例如:

command ls    # 确保执行的是 /bin/ls 而不是别名

4. 查看所有内置命令​

在 bash 中,可以使用以下命令列出所有内置命令:

help          # 显示 Shell 内置命令列表
help cd # 显示内置命令 cd 的帮助
compgen -b # 列出所有 Shell 内置命令

在 zsh 下,没有 help 和 compgen -b 命令,想列出所有的内置命令可以试试 enable,效果与 compgen -b 相似,所以上文说 zsh 与 bash 兼容,也不对,命令都不一样。