当前位置: 首页 > news >正文

Linux——7.如何理解 shell

一、Shell 的类型:不同解释器的特点与适用场景

1. 主流 Shell 类型及其特点

Bash(Bourne Again SHell)

  • 最广泛使用的 Shell,默认安装于大多数 Linux 发行版和 macOS。
  • 兼容 sh 语法,支持命令补全、历史记录(history命令)、管道(|)、重定向(>)等高级功能。
  • 配置文件:用户级(~/.bashrc~/.bash_profile),系统级(/etc/bash.bashrc/etc/profile)。

Zsh

  • 基于 Bash,功能更强大,支持主题(如 Oh My Zsh 框架)、高级补全(自动补全路径、命令参数)、插件系统。
  • 适合开发者和极客,配置更灵活(通过.zshrc)。

Fish(Friendly Interactive Shell)

  • 以用户友好为设计目标,自动补全(黄色提示)、彩色输出、语法高亮。
  • 不兼容 Bash 语法,但提供fish_mode命令兼容部分 Bash 脚本。

Tcsh/Csh

  • 基于 C 语言语法的 Shell,支持命令别名、历史记录,但功能较 Bash 简单。
  • 历史悠久,部分老系统仍在使用(如 FreeBSD 默认 Csh)。

Dash(Debian Almquist Shell)

  • 轻量级 Shell,用于系统脚本(如/bin/sh通常指向 Dash)。
  • 执行速度快,但功能有限,主要用于启动脚本和系统工具。
2. 如何切换 Shell
  • 查看当前 Shell:echo $SHELL 或 ps -p $$$$是当前 Shell 的 PID)。
  • 查看系统可用 Shell:cat /etc/shells
  • 临时切换:bashzshfish 等(直接输入 Shell 名称)。
  • 永久切换:chsh -s /bin/zsh username(需重启终端生效)。

二、Shell 的父子关系:进程树与命令执行机制

1. 父子 Shell 的概念
  • 父 Shell:启动其他 Shell 的进程(如终端模拟器启动的初始 Shell)。
  • 子 Shell:由父 Shell 创建的新 Shell 进程(如执行脚本、(命令)bash等)。

示例:通过 PID 查看父子关系

echo $$  # 当前Shell的PID(如1234)
bash     # 启动子Shell
echo $$  # 子Shell的PID(如1235,父PID为1234)
exit     # 退出子Shell,回到父Shell
2. 子 Shell 的创建场景
  • 执行脚本./script.sh 会创建子 Shell 执行脚本(除非用source.在当前 Shell 执行)。
  • 命令分组(cd /tmp; ls) 会在子 Shell 中执行括号内的命令(不影响父 Shell 的工作目录)。
  • 管道echo "hello" | while read line; do echo $line; done 中,while循环在子 Shell 中执行(变量在子 Shell 内有效)。
  • 后台任务(sleep 5; echo "done") & 会创建子 Shell 在后台执行命令。
3. 父子 Shell 的变量传递规则
  • 父→子:父 Shell 的环境变量(export声明的变量)会传递给子 Shell。
    # 父Shell
    export NAME=Alice  # 环境变量
    VAR=Bob            # 普通变量
    bash               # 进入子Shell# 子Shell
    echo $NAME  # 输出: Alice(继承父Shell的环境变量)
    echo $VAR   # 输出: (普通变量未传递)
    exit# 父Shell
    echo $VAR   # 输出: Bob(子Shell修改不影响父Shell)
    
  • 子→父:子 Shell 无法直接修改父 Shell 的变量(除非通过文件或进程间通信)。

三、进程列表:Shell 与进程的交互

1. Shell 如何管理进程
  • Shell 是用户与系统进程交互的桥梁,负责:
    • 创建进程(执行命令)。
    • 控制进程状态(前台 / 后台、暂停 / 恢复)。
    • 传递信号(如Ctrl+C发送 SIGTERM 终止进程)。
2. 查看 Shell 创建的进程
  • jobs命令:查看当前 Shell 的后台任务。
    sleep 100 &  # 后台执行sleep命令
    jobs         # 输出: [1]+  Running                 sleep 100 &
    
  • ps命令:结合-f(完整信息)和-p(指定 PID)查看特定进程。
    ps -f -p $$  # 查看当前Shell的进程信息
    
3. 控制进程状态
  • 前台→后台Ctrl+Z暂停进程,bg %1将任务 1 放至后台继续执行。
  • 后台→前台fg %1将任务 1 调至前台。
  • 终止进程kill %1(终止后台任务 1)或Ctrl+C(终止前台进程)。

四、 Shell 灵活控制命令执行环境

1. 隔离环境执行命令
  • 场景:临时切换目录或环境变量,不影响当前 Shell。
    (cd /tmp; ls)  # 在子Shell中切换到/tmp并执行ls,父Shell仍在原目录
    
2. 并行执行多任务
  • 场景:同时执行多个耗时任务(如备份、下载)。
    (tar -czf backup1.tar.gz /home &)  # 子Shell中后台执行备份
    (tar -czf backup2.tar.gz /var &)   # 另一个子Shell并行执行
    wait  # 等待所有后台任务完成(可选)
    
3. 防止脚本修改当前环境
  • 场景:执行未知脚本时,避免脚本修改当前 Shell 的变量或状态。
    (source unknown_script.sh)  # 在子Shell中执行,即使脚本修改环境变量,也只影响子Shell
    
4. 简化管道命令的变量传递(Bash 4+)
  • 传统管道中,右侧命令在子 Shell 执行,变量无法传递到父 Shell。
    • 问题
      echo "123" | read num
      echo $num  # 输出为空(read在子Shell执行,num变量丢失)
      
    • 解决方案(Bash 4+):使用lastpipe选项(让管道最后一个命令在当前 Shell 执行)。
      shopt -s lastpipe  # 启用lastpipe
      echo "123" | read num
      echo $num  # 输出: 123
      

五、Shell 的内建命令与外部命令:执行机制的差异

1. 外部命令:独立的可执行程序
  • 定义:存储在文件系统中的独立程序(如/bin/ls/usr/bin/grep)。
  • 执行机制:Shell 创建子进程(fork)加载并执行程序,执行完毕后子进程退出。
  • 特点
    • 执行前需从磁盘加载,有一定开销。
    • 可通过which 命令type -a 命令查看位置。

示例

which ls     # 输出: /bin/ls
type -a grep # 输出: grep is /usr/bin/grep
2. 内建命令:Shell 自身实现的功能
  • 定义:Shell 内部实现的命令,无需创建子进程,直接在当前 Shell 执行。
  • 执行机制:Shell 解析命令后直接调用内部函数处理。
  • 常见内建命令cdechoexportsourcealiasexit等。

示例

type cd      # 输出: cd is a shell builtin
type echo    # 输出: echo is a shell builtin
3. 内建与外部命令的核心区别
特性内建命令外部命令
执行位置当前 Shell 进程内子进程中执行
效率无进程创建开销,速度快需创建子进程,有开销
对 Shell 的影响可直接修改 Shell 状态(如 cd)无法修改父 Shell 状态(如 cd 无效)
查看方式type 命令显示 "builtin"which 命令显示路径
4. 为什么需要内建命令?
  • 状态修改:如cdexport需直接修改当前 Shell 的工作目录或环境变量,子进程无法影响父 Shell。
  • 效率优化:频繁使用的命令(如echopwd)通过内建实现可减少进程创建开销。

相关文章:

  • C#图书管理系统笔记(残缺版)
  • STM32F103C8T6 学习笔记摘要(四)
  • 前端截图并导出pdf
  • dify应用实践教程5
  • 量子机器学习前沿:量子神经网络与混合量子-经典算法
  • 【图片识别改名】自动识别图片中的文字并给图片命名 ,图片自动识别并且能重命名的操作步骤和注意事项
  • Spark基于Bloom Filter算法的Runtime Filter Join优化机制
  • 【论文阅读35】-PINN review(2021)
  • AI编程再突破,文心快码发布行业首个多模态、多智能体协同AI IDE
  • 【LeetCode】用双指针解决移除元素问题、合并两个有序数组求解
  • 基于openfeign拦截器RequestInterceptor实现的微服务之间的夹带转发
  • 搭建网站时用到的技术
  • VoiceAgent技术赋能债务重组:合规、高效、有温度的金融债务解决方案
  • Java面试复习指南:基础、并发、JVM与Spring框架
  • 零基础学习RabbitMQ(2)--Linux安装RabbitMQ
  • 硬件工程师笔试面试高频考点汇总——(2025版)
  • (LeetCode 面试经典 150 题) 27.移除元素
  • Spring Boot:运用Redis统计用户在线数量
  • 百度AIP:Springboot人脸对比
  • 【钓鱼预警】针对跨境销售投递Tesla间谍木马
  • 网页设计制作音乐网站/打广告去哪个平台免费
  • 学校网站建设行业现状/太原百度网站快速优化
  • 大良网站设计/广告推广平台网站有哪些
  • 公司注册官方网站/陕西网站seo
  • 夜夜做新郎网站在线视频/网店代运营公司靠谱吗
  • 网站页面优化/最大的搜索网站排名