• shell启动后—->>进程:使用PID号进行区分,(在系统中,一个进程只认为自己存在)
  • 父shell与子shell相互独立(父子shell之间环境相互独立)
  • cat /etc/shells/:查看当前系统所支持的shell程序

4.1bash特性:

4.1.1命令历史:.bash_history
  • history:

    • -d:删除历史命令(history -d 第几行(开始) [连续几行]
    • -c:清空当前内存的命令历史
    • -w:将命令历史保存到某个文件中
    • 使用技巧:

      • !n:执行命令历史中的第n行命令
      • !-n:执行命令历史中的倒数第n行命令
      • !word:执行命令历史中最近一次的Word命令
      • !!:执行上一条命令
      • !$:引用运行的这个命令的之前所用过的最后一个参数

        1. ESC键(按完松开). 键(按完松开)

4.1.2 管道,IO重定向:|
  • 计算机体系结构:
    • 控制器:CPU
    • 运算器:CPU
    • 存储器:RAM:内存
    • 输入设备:(input):键盘、鼠标
    • 输出设备:(output):屏幕、打印机
  • 计算机总线:
    • 地址总线:负责内存寻址
    • 数据总线:负责传输数据
    • 控制总线:负责控制指令
  • 寄存器:CPU中内部临时存储空间
  • I/O设备:负责计算机内部存储设备和外部存储设备(硬盘、光盘)
  • 程序:指令+数据
    • 指令:有程序提供,负责加工数据
    • 数据:系统中数据可以有多个数据来源,比如来自变量、文件、输入设备
  • 标准输入输出设备:
    • 标准输入设备:键盘(stdin),文件描述符:0
    • 标准输出设备:显示器(stdout),文件描述符:1
    • 标准错误输出设备:显示器(stderr),文件描述符:2
  • 三种数据流:
    • 标准输入数据流 / 标准输出数据流 / 标准错误输出流
  • 当在Linux中打开一个文件时,内核会反复调用,对于文件标识就很重要,用文件描述符来标识文件,文件加载完用数字标识 :fd(file descriptor)

IO重定向:把默认输入输出来源,重新定向到其他的文件或设备:

  • 输出重定向:
    • :覆盖输出重定向

    • :追加输出重定向

    • 2>:错误覆盖输出重定向
    • 2>>:错误追加输出重定向
    • &>:混合覆盖输出重定向
    • &>>:混合追加输出重定向
  • 输入重定向:
    • <:输入重定向
  • |(管道):连接多条命令,把前一条命令的输出结果作为后一条命令的输入条件
    • 格式:command1 | command2 | command3 | …..
    • 思路:北京 、河北保定、河北大学、 找 2018级 计算机系 3班 张三 (组合小程序,完成实现大功能)
    • tr命令:实现字符转换:tr ’a-z‘ ’A-Z‘
    • tee命令:把数据重定向到给定文件和屏幕上
    • 管道使用例子:cat /etc/passwd | tr ‘a-z’ ‘A-Z’

4.1.2扩展—— 重定向的具体讲解

1.文件描述符
  • linux文件描述符:可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作。
  • 三个默认的文件描述符
    • 标准输入:standard input 0 (默认设备键盘)
    • 标准输出:standard output 1(默认设备显示器)
    • 错误输出:error output 2 (默认设备显示器)
  • 注意:

(1)以后再打开文件,描述符可以依次增加
(2)一条shell命令,都会继承其父进程的文件描述符,因此所有的shell命令,都会默认有三个文件描述符。

(3) 文件所有输入输出都是由该进程所有打开的文件描述符控制的。(Linux一切皆文件,就连键盘显示器设备都是文件,因此他们的输入输出也是由文件描述符控制)

(4) 一条命令执行以前先会按照默认的情况进行绑定(也就是上面所说的 0,1,2),如果我们有时候需要让输出不显示在显示器上,而是输出到文件或者其他设备,那我们就需要重定向。

(5)下面的学习注意理解重定向的含义。将标准的重定向到自定义的。

2.重定向
  • 输入重定向 :<<<
  • 输出重定向 :>>>
  • 注意:此处涉及到shell的解析原理,仅做简单介绍
    • bash 在执行一条指令的时候,首先会检查命令中存不存在重定向的符号,如果存在那么首先将文件描述符重定向(之前说过了,输入输出操作都是依赖文件描述符实现的,重定向输入输出本质上就是重定向文件描述符),然后再把重定向去掉,执行指令
    • 如果指令中存在多个重定向,那么不要随便改变顺序,因为重定向是从左向右解析的,改变顺序可能会带来完全不同的结果
    • < 是对标准输入 0 重定向 ,> 是对标准输出 1 重定向
    • 再强调一下, 重定向就是针对文件描述符的操作

3.输入重定向
  • 格式: [n]< file:n是文件描述符。[]与<之间没有空格
  • 说明:将文件描述符 n 重定向到 word 指代的文件(以只读方式打开),如果n省略就是0(标准输入、键盘)

4. shell脚本 - 图1

4. shell脚本 - 图2

  • 解释:解析器解析到 “<” 以后会先处理重定向,将标准输入重定向到file,之后cat再从标准输入读取指令的时候,由于标准输入已经重定向到了file ,于是cat就从file中读取指令了。第二张图片,先定义了重定向,然后读cat文件

4. shell脚本 - 图3

4.输出重定向
  • 格式: [n]> file
  • 说明: 将文件描述符 n 重定向到word 指代的文件(以写的方式打开),如果n 省略则默认就是 1(标准输出)

4. shell脚本 - 图4

4. shell脚本 - 图5

  • 第二张图同样是 先进行重定向,然后使用echo命令

4. shell脚本 - 图6

5.标准输出与标准错误输出重定向
  • 格式: &> word>& word
  • 说明:将标准输出标准错误输出都定向到word代表的文件(以写的方式打开),两种格式意义完全相同,这种格式完全等价于 > word 2>&1 (2>&1 是将标准错误输出复制到标准输出,&是为了区分文件1和文件描述符1的)

4. shell脚本 - 图7

  • 解释:我们首先执行了一个错误的命令,可以看到错误提示被写入文件(正常情况下是会直接输出的),我们又执行了一条正确的指令,发现结果也输入到了文件,说明正确错误消息都能输出到文件。(&>是混合错误输出重定向

4. shell脚本 - 图8

6.文件描述符的复制
  • 格式: [n]<&[m][n]>&[m] (这里的所有字符之间不能有空格)
  • 说明:
    • 这里两个都是将文件描述符 n 复制到 m ,两者的区别是,前者是以只读的形式打开,后者是以写的形式打开
    • 这里的& 目的是为了区分数字名字的文件和文件描述符,如果没有& 系统会认为是将文件描述符重定向到了一个数字作为文件名的文件,而不是一个文件描述符
  • 一定要注意:重定向符号不能随意换位置
    • cmd > file 2>&1
    • cmd 2>&1 >file
    • 第二句的意思是,先将标准错误输出重定向到1(显示器),然后将标准输出重定向到file,与第一句不同
    • 4. shell脚本 - 图9

7. exec 绑定重定向
  • 格式:exec [n]< file/[n]exec > file/[n]
  • 注意:
    • 格式: exec [n]<>file
    • 说明:以读写方式打开file指代的文件,并将n重定向到该文件。如果n不指定的话,默认为标准输入。
    • exec仅仅对随后的一条重定向指令有效,第二条向后就失效了

4. shell脚本 - 图10

4. shell脚本 - 图11

8.HERE文件
  • 格式:<<[-]EOF
  • 说明:指定shell从当前输入源中读入行直至遇到仅包含EOF的一行(EOF后面也不能有空白符),然后所有读入的内容(不包括最后一行)作为标准输入传递给指令。‘-‘的作用是将每一行前面的tab去除后再读入。需要注意的是这个EOF不会进行任何扩展,但是如果EOF中没有字符没引号扩起来,那么here-document中的内容可以进行参数扩展、指令替换以及算术扩展(parameterexpansion, command substitution, and arithmeticexpansion);只要有任一字符被引号扩起来,delimiter仍是将去除引号的EOF,但是输入行不会进行任何扩展。
  • 示例:
    $ cat <<EOF
    > $(pwd)     # 指令替换
    > `pwd`      # 指令替换的第2种形式
    > $HOME      # 参数扩展
    > $((4+5))   # 算数扩展
    > EOF
    /home/leo        //此处开始扩展
    /home/leo
    /home/leo
    9
    $ cat <<"EOF"
    > $(ls)
    > `pwd`
    > $HOME
    > $((4+5))
    > EOF
    $(ls)              //因为EOF有双引号,所以不会被扩展
    `pwd`
    $HOME
    $((4+5))
    

9.HERE字符串
  • 格式:<<<word
  • 说明:将扩展后的word作为标准输入传递给指令。
    • 举例:使用这个功能可以将指令
      echo ‘something’ |command
      通过下面这种方式来实现
      command <<<’something’

4.1.3 命令别名:(使用alias定义的别名只在当前shell中生效)
  • alias: alias ll=‘ls -l’(等号后不能有空格,等号后用英文单引号、双引号引起来)
  • unalias:unalias 命令别名

4.1.4 命令行编辑
  • Ctrl+a:光标快速跳转到命令行行首
  • Ctrl+e:光标快速跳转到命令行行尾
  • Ctrl+u:快速删除光标位置到命令行行首的字符
  • Ctrl+k:快速删除光标位置到命令行行尾的字符
  • Ctrl+l :清屏(clear)

4.1.5 命令行展开
  • 命令补齐:在path变量中搜索命令并补齐(不能补齐选项)
  • 路径和文件补齐:在系统路径中查找
  • 命令替换:(常用在编程中)
    • 将命令中的子命令替换成子命令执行结果的过程:$(command)、commamd(两边是反撇号)
    • " "(双引号):弱引用(可是实现变量的替换,把变量名替换为变量值)
    • ``(反撇号):命令引用
    • ‘’(单引号) :强引用,不会替换
 4.1.6 命令行通配
    • :匹配任意长度的任意字符
  • ?:匹配任意单个字符
  • []:匹配指定范围内的任意字符:[ab][a-z][A-Z][0-9][a-zA-Z][a-zA-Z0-9 ]
  • [^]:匹配指定范围外的任意字符
  • [:space:]:代表空格
  • [:punct:]:表示所有标点字符
  • [:lower:]:表示所有小写字母
  • [:upper:]:表示所有大写字母
  • [:alpha:]:表示所有字母(包括大小写)
  • [:digit:]:表示所有数字
  • [:alnum:]:表示所有数字和大小写字母

4.1.7 变量

4.1.8 编程