一、 知识框架与概念理解

1. 什么是Shell?

  • 概念:Shell是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。

  • 本质:它是一个应用程序,提供界面让用户访问操作系统内核的服务。

  • Shell脚本:为Shell编写的脚本程序,文件后缀通常为 .sh

  • Shebang(#!):脚本文件的第一行 #!/bin/bash 用于指定解释此脚本的Shell路径。

2. Shell的类型

Linux的Shell种类众多,常见的有:

  • Bourne Shell (/usr/bin/sh/bin/sh)

  • Bourne Again Shell (/bin/bash) —— 日常工作中广泛使用,也是大多数Linux系统默认的Shell。

  • C Shell (/usr/bin/csh)

  • K Shell (/usr/bin/ksh)

  • Shell for Root (/sbin/sh)

注意#!/bin/sh 在很多系统中同样可以改为 #!/bin/bash

3. 默认Shell的配置

系统启动什么样的Shell程序取决于用户ID配置。

  • 配置文件位置:/etc/passwd 文件中的第7个字段。

  • 实操命令

    bash

    cat /etc/passwd | grep zhang
    # 输出示例:zhang:x:1000:1000:Jinyuan Zhang:/home/zhang:/bin/bash
  • 其他Shell启动:输入 /bin/dash 启动dash,输入 exit 退出。


二、 Shell的父子关系与运行模式

1. 父子Shell关系

  • 用户登录虚拟控制台或启动终端仿真器时,启动的默认交互Shell是一个父Shell

  • 在CLI提示符后输入 bash 命令,会创建一个新的Shell程序,称为子Shell(child shell)

  • 实操命令

    • ps -f:查看进程ID(PID)和父进程ID(PPID)。

    • ps --forest:展示子Shell间的嵌套结构。

    • exit:有条不紊地退出子Shell。

    • man bashbash --help:获取bash命令的帮助。
      (请在此处插入Xshell中执行 ps --forestexit 的截图)

2. 命令列表与进程列表

  • 命令列表:在命令之间加入分号(;),可以在一行中依次运行一系列命令。

  • 进程列表:将命令列表包含在括号 () 里,会生成一个子Shell来执行对应的命令。

  • 判断是否生成子Shell:使用 echo $BASH_SUBSHELL。返回 0 表示没有子Shell,返回 1 或更大数字表示存在子Shell。

  • 实操命令

    bash

    pwd; ls; cd ./directory/; pwd; echo $BASH_SUBSHELL
    (pwd; ls; cd ./directory/; pwd; echo $BASH_SUBSHELL)

    (请在此处插入Xshell中执行上述命令的对比截图)

3. 后台模式与协程

  • 后台模式:在命令末尾加上字符 &,让出CLI供他用。

    • sleep 60 &:将命令置入后台。

    • ps -fjobs:显示各种进程和后台作业信息。jobs -l 显示更详细信息。

    • 进程列表置入后台:(pwd; ls; cd ./directory/; pwd; echo $BASH_SUBSHELL) &

  • 协程(coproc):在后台生成一个子Shell,并在这个子Shell中执行命令。默认名字为 COPROC

    • 扩展语法:coproc My_Job { sleep 10; } (注意:{} 和命令名之间必须有空格,命令必须以分号 ; 结尾)。
      (请在此处插入Xshell中执行 jobs -l 查看后台任务的截图)


三、 内建命令与外部命令

1. 概念区分

  • 外部命令:存在于bash shell之外的程序,通常位于 /bin/usr/bin/sbin/usr/sbin 中。执行时会创建子进程(衍生/forking),需要花费时间和精力设置新子进程的环境。ps 就是一个外部命令。

  • 内建命令:已经和shell编译成了一体,不需要借助外部程序文件来运行,不需要子进程,执行速度更快,效率更高。cdexit 都是内建命令。

2. 查看命令类型

  • which:只显示外部命令文件。

  • type -a:查看命令的不同实现(包括内建和外部)。

  • 实操命令

    bash

    which ps
    type -a ps
    type -a cd
    type -a echo
    type -a pwd

    (请在此处插入Xshell中执行 type -a 的截图)


四、 核心内建命令实战 (history 与 alias)

1. history 命令

history 会跟踪你用过的命令。命令历史记录先存放在内存中,当shell退出时(当前终端窗口关闭时)才被写入到隐藏文件 .bash_history 中(位于用户主目录)。

  • 唤回命令

    • !!:唤出刚刚用过的那条命令。

    • !命令编号:唤出history中对应编号的命令。

    • history | grep 27:查找历史记录。

  • 实操命令

    bash

    ps --forest
    !!
    !27

【课后练习题解答】

题目1:查看history和cat .bash_history输出有什么不同?
解答
在Xshell中执行 tail -5 .bash_historyhistory | tail -5
.bash_history 的末尾几行是上次退出shell时的命令;而 history 的末尾是当前实时输入过的命令(存在内存中,还未写入文件)。两者由于时间差,输出通常是不一致的。
(请在此处插入 tail -5 .bash_historyhistory | tail -5 的对比截图)

题目2:执行history -a后cat .bash_history输出有什么变化?
解答
history -a 选项的作用是强制将内存中的命令历史记录写入 .bash_history 文件(而不必等到退出shell)。
执行 history -a 后,再次执行 tail -5 .bash_history,你会发现 .bash_history 的内容与 history 命令的内容变得一致了,刚刚执行的命令被追加到了文件中。
(请在此处插入执行 history -a 后再 tail -5 .bash_history 的截图)

2. alias 命令

alias(别名)允许你为常用的命令(及其参数)创建另一个名称,从而减轻代码输入量。

  • alias -p:查看当前Linux发行版已经设置好的常用命令别名(如 llls -al 显示结果一样)。

  • 创建别名:alias li='ls -li'

  • 注意:命令别名属于内部命令,一个别名仅在它所被定义的shell进程中才有效。在自己用户下设置的别名,不会影响其他用户。

  • 实操命令

    bash

    alias -p
    alias li='ls -li'
    li
Logo

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

更多推荐