深入理解Shell:类型、进程、运行模式与常用内建命令
·
1. Shell的类型
Shell是用户与操作系统内核之间的命令行接口,主要分为以下几类:
1.1 Bourne Shell (sh)
- 起源:1977年由Stephen Bourne在贝尔实验室开发
- 特点:Unix系统的标准Shell,语法简洁,执行效率高
- 常见位置:
/bin/sh - 现状:现代系统中通常作为其他Shell的兼容模式存在
1.2 Bash (Bourne-Again Shell)
- 起源:1989年Brian Fox为GNU项目开发
- 特点:sh的增强版,支持命令历史、命令行编辑、作业控制等
- 常见位置:
/bin/bash - 现状:Linux系统和macOS的默认Shell
1.3 Zsh (Z Shell)
- 起源:1990年由Paul Falstad开发
- 特点:Bash的扩展,支持更强大的补全、主题和插件系统
- 常见位置:
/bin/zsh - 现状:macOS Catalina及以后版本的默认Shell
1.4 其他Shell
- C Shell (csh):类C语法,支持命令历史
- Korn Shell (ksh):结合了sh和csh的特性
- Fish:友好的交互式Shell,语法高亮和自动建议
2. Shell进程及其关系
2.1 什么是Shell进程
当用户在终端输入命令时,操作系统会创建一个Shell进程来执行该命令。每个终端会话通常对应一个Shell进程。
2.2 进程关系示例
# 查看当前Shell的进程ID
echo $$
# 查看父进程ID
echo $PPID
# 查看进程树
pstree -p $$
3. Shell的父子关系
3.1 父子进程创建
当Shell执行外部命令时,会创建子进程:
# 执行ls命令,Shell会创建子进程
ls -l
# 使用&在后台运行,同样创建子进程
sleep 60 &
3.2 进程继承关系
- 子进程继承父进程的环境变量
- 子进程可以修改自己的环境变量而不影响父进程
- 子进程结束后会向父进程返回退出状态
3.3 示例:观察父子进程
# 脚本示例:parent.sh
#!/bin/bash
echo "父进程PID: $$"
echo "父进程名称: $0"
# 创建子进程
sleep 30 &
child_pid=$!
echo "子进程PID: $child_pid"
# 等待子进程结束
wait $child_pid
echo "子进程已结束,退出状态: $?"
4. Shell的运行模式
4.1 交互式模式 (Interactive Mode)
- 特点:用户直接与Shell交互,显示提示符
- 启动方式:直接打开终端或通过ssh连接
- 配置文件:
.bashrc、.zshrc等 - 示例:日常在终端中输入命令
4.2 非交互式模式 (Non-interactive Mode)
- 特点:执行脚本或通过管道传递命令
- 启动方式:
bash script.sh或echo "ls" | bash - 配置文件:
.bash_profile、.profile等 - 示例:自动化脚本执行
4.3 登录Shell (Login Shell)
- 特点:用户登录时启动的Shell
- 启动方式:系统登录、
su - username、bash --login - 配置文件:
.bash_login、.profile等 - 读取文件顺序:
/etc/profile~/.bash_profile~/.bash_login~/.profile
4.4 非登录Shell (Non-login Shell)
- 特点:在已登录会话中启动的新Shell
- 启动方式:直接运行
bash、打开新终端标签 - 配置文件:
.bashrc - 示例:在终端中直接输入
bash命令
5. 内建命令和外部命令
5.1 内建命令 (Built-in Commands)
- 定义:直接内置于Shell解释器中的命令
- 特点:
- 执行速度快(无需创建新进程)
- 可以影响Shell自身状态
- 通常用于Shell环境控制
- 常见内建命令:
cd:改变目录echo:输出文本export:设置环境变量source或.:执行脚本exit:退出Shell
5.2 外部命令 (External Commands)
- 定义:独立的可执行文件
- 特点:
- 存储在文件系统中
- 执行时需要创建新进程
- 通过PATH环境变量查找
- 示例:
ls:/bin/lsgrep:/bin/greppython:/usr/bin/python
5.3 判断命令类型
# 使用type命令判断
type cd # 输出: cd is a shell builtin
type ls # 输出: ls is /bin/ls
type -a echo # 显示所有echo命令的位置
# 使用command命令强制使用外部命令
command -v ls # 显示命令路径
builtin echo # 强制使用内建echo
6. 内建命令history的用法
6.1 基本使用
# 查看命令历史
history
# 查看最近10条历史
history 10
# 清空历史记录
history -c
# 删除指定行历史
history -d 行号
6.2 历史记录配置
# 查看历史记录相关环境变量
echo $HISTSIZE # 内存中保存的历史数量
echo $HISTFILESIZE # 历史文件中保存的行数
echo $HISTFILE # 历史文件路径
# 设置历史记录选项
export HISTSIZE=5000
export HISTFILESIZE=10000
export HISTCONTROL=ignoreboth # 忽略重复命令和空格开头的命令
export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S " # 为历史添加时间戳
6.3 实用技巧
# 快速执行历史命令
!! # 执行上一条命令
!-2 # 执行倒数第二条命令
!ls # 执行最近以ls开头的命令
!?data? # 执行最近包含data的命令
# 搜索历史命令
Ctrl+R # 反向搜索历史
Ctrl+S # 正向搜索历史(可能需要stty设置)
# 历史命令替换
^old^new # 将上一条命令中的old替换为new后执行
!!:gs/old/new/ # 全局替换
6.4 历史记录管理
# 将当前会话历史追加到文件
history -a
# 从历史文件重新加载历史
history -r
# 将内存历史写入文件并清空内存
history -w && history -c
7. 内建命令alias的用法
7.1 创建别名
# 基本语法
alias 别名='原命令 参数'
# 常用示例
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias grep='grep --color=auto'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
# 带参数的别名(需要使用函数)
alias lsd='ls -d */' # 只显示目录
7.2 查看别名
# 查看所有别名
alias
alias -p
# 查看特定别名
alias ll
alias ls grep
7.3 删除别名
# 删除单个别名
unalias ll
# 删除所有别名
unalias -a
7.4 永久化别名
# 添加到Shell配置文件
# ~/.bashrc (Bash) 或 ~/.zshrc (Zsh)
# 示例.bashrc内容
alias ll='ls -alF'
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias h='history'
alias j='jobs -l'
alias path='echo -e ${PATH//:/\\n}'
7.5 实用别名示例
# 系统监控
alias cpu='top -o cpu'
alias mem='top -o rsize'
alias ports='netstat -tulanp'
# Git相关
alias gs='git status'
alias ga='git add'
alias gc='git commit'
alias gp='git push'
alias gl='git log --oneline --graph --all'
# 安全相关
alias rm='rm -i' # 删除前确认
alias cp='cp -i' # 覆盖前确认
alias mv='mv -i' # 覆盖前确认
# 网络相关
alias myip='curl ifconfig.me'
alias ping='ping -c 5'
alias ports='netstat -tulanp'
# 开发相关
alias py='python3'
alias pip='pip3'
alias venv='python3 -m venv'
7.6 别名与函数结合
# 创建带参数的别名函数
# 在.bashrc或.zshrc中添加
mkcd() {
mkdir -p "$1" && cd "$1"
}
# 使用
mkcd new_project
8. 总结
Shell作为用户与操作系统交互的重要桥梁,理解其类型、进程关系、运行模式以及内建命令的使用,能够显著提高命令行工作效率。通过合理使用history和alias,可以打造个性化的高效工作环境。
8.1 最佳实践建议
- 选择合适的Shell:根据需求选择Bash、Zsh等
- 理解进程关系:避免不必要的子进程创建
- 配置运行模式:正确设置登录和非登录Shell的配置文件
- 善用历史记录:配置HISTCONTROL和HISTTIMEFORMAT
- 创建实用别名:将常用命令组合封装为别名
8.2 进一步学习资源
-
Bash官方文档:
man bash -
Zsh官方文档:
man zsh -
Advanced Bash-Scripting Guide
-
ShellCheck工具:静态Shell脚本分析
-

-


openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)