【Shell学习笔记篇】

299 阅读5分钟

一、基础知识

核心命令
  • 筛选命令相关:

  • 快捷键:

    • !! 执行上一条命令
    • !num num为历史命令编号,可以输入history查看历史命令
    • Ctrl + r 根据输入的关键字查找历史命令
  • 命令行切换:

    • Ctrl + A 光标迅速回到行首
    • Ctrl + E 光标迅速回到行尾
    • Esc + b 移动到当前单词的开头
    • Esc + f 移动到当前单词的结尾
    • Ctrl + k 删除光标到行尾的内容
    • Ctrl + u 删除光标到行首的内容
    • Ctrl + y 粘贴删除的内容
    • Ctrl + c 临时停止命令行命令
  • grep 查询文件中的内容

    • 格式:grep 参数 查询的内容 文件名

    • 参数:

      • -i 不区分大小写
      • -n 显示行号
      • -v 对查询的内容取反
      • -w 按单词查询
      • -o 打印匹配关键字
      • -c 统计匹配的次数
      • -r 逐层遍历目录查询
      • -Anum 查询多少行的后几行
      • -Bnum 查询多少行的前几行
      • -Cnum 查询多少行的前后几行
      • -l 只列出匹配的文件名
      • -L 列出不匹配的文件名
      • -e 使用正则匹配
      • ^关键字 返回行首以关键字开头的文件路径
      • 关键字$ 以关键字结尾
      • ^$ 匹配空行
      • --color=auto 可以给查询到的内容添加颜色
  • sort 对文件内容排序

    • 格式:sort 参数 文件名

      • -u 去重
      • -r 降序,默认为升序
      • -o 对排序后的文件重新写入另一个文件
      • -n 以数字进行升序,默认是按字符排序
      • -t 分隔符
      • -b 忽略前导空格
      • -R 随机排序
  • 信息处理命令相关:

  • cut 数据截取

    • 格式:cut 参数 文件名

      • -b 只截取指定的字节
      • -c 只截取指定的字符
      • -d 按分隔符进行截取
      • -f 截取每行中的第几列,要想获取多列需要用逗号隔开
      • cut -d: -f1 a.txt: 进行切割并获取第一列的数据
  • tr 数据缩减、替换、删除

    • -c 根据指定的关键字符进行替换字符前后的数据

      • tr -c ":" "@" < a.txt 会将: 前后替换为@
    • -s 根据指定的关键字符进行缩减

      • tr -s " " < a.txt 将行首的多个空格缩减为一个空格
    • -d 根据指定的关键字进行删除

      • tr -d ":" < a.txt 删除文件中包含: 符号
    • tr "root" "ROOT" < a.txt 将小写的root替换成大写的ROOT

  • uniq 连续去重

    • -c 计数去重的个数

      • uniq -c a.txt
    • -i 不区分大小写

    • -d 只显示去重的内容

    • -n 显示行号

  • 组合信息相关命令:

  • paste 合并文件行输出到屏幕,但不会改变数据源

    • -d 指定每列之间的分隔符 paste -d'@' a.txt
    • -s 将多行转为一行输出
  • xargs 命令结果传递

    • 作用:可以将管道符或标准输入数据转换成命令行参数,也能够从文件的输出中读取数据

    • 格式:命令 | xargs 参数 命令

    • -a 从文件中读取数据作为标准输入

      [root@VM-12-9-centos num]# xargs -a a.txt
      aaa bbb
      
    • -E 读取数据时以分隔符进行分隔

      [root@VM-12-9-centos num]# xargs -a a.txt -n 2 -p -E " " 
      echo aaa bbb ?...y
      aaa bbb
      
    • -p 每次读取数据时询问用户

      [root@VM-12-9-centos num]# xargs -a a.txt -n 1 -p
      echo aaa ?...y
      aaa
      
    • -n num 执行命令时一次所使用的个数,默认是所有的

      [root@VM-12-9-centos num]# xargs -a a.txt -n 1
      aaa
      bbb
      
    • -t 先打印命令然后再执行

    • -I 将接受的数据逐行赋值给{} ,相当于将结果临时存储在{} 中,也可以当变量使用

      [root@VM-12-9-centos num]# xargs -a a.txt -I {} echo {}-结果
      aaa-结果
      bbb-结果
      
      [root@VM-12-9-centos num]# ls *.txt | xargs -I {} cp {}  /usr/local/{}
      查看所有以txt结尾的文件,并将它们复制到/usr/local/原文件 下
      
    • -r 当输入为空时停止执行该命令

    • -d 分隔符,默认的分隔符是空格,可以通过该参数指定分隔符

      [root@VM-12-9-centos num]# echo "xnamexnamexnamexname" | xargs -d "x"
       name name name name
      
shell基础
  • 脚本的执行方法

    1️⃣ 强烈推荐:

    [root@VM-12-9-centos shell]# /bin/bash /usr/local/getNetWorkDataInfo.sh 
    IP:  172.17.0.1
    Netmask:  255.255.0.0
    Broadcast:  172.17.255.255
    MAC Address:  02:42:89:d8:ad:30
    

    2️⃣ 执行需要权限

    [root@VM-12-9-centos shell]# ./getNetWorkDataInfo.sh
    -bash: ./getNetWorkDataInfo.sh: 权限不够
    

    3️⃣ 不推荐

    [root@VM-12-9-centos shell]# . getNetWorkDataInfo.sh 
    IP:  172.17.0.1
    Netmask:  255.255.0.0
    Broadcast:  172.17.255.255
    MAC Address:  02:42:89:d8:ad:30
    当然 . 还可以换成 source
    

    4️⃣ 1的变种版:

    [root@VM-12-9-centos shell]# cat getNetWorkDataInfo.sh | bash
    IP:  172.17.0.1
    Netmask:  255.255.0.0
    Broadcast:  172.17.255.255
    MAC Address:  02:42:89:d8:ad:30
    
  • 脚本的调试:

    -n 检查脚本中的语法错误

    [root@VM-12-9-centos shell]# /bin/bash -n getNetWorkDataInfoError.sh 
    getNetWorkDataInfoError.sh:行8: 寻找匹配的 `"' 是遇到了未预期的文件结束符
    getNetWorkDataInfoError.sh:行9: 语法错误: 未预期的文件结尾
    

    -v 逐行执行并显示结果,遇到错误显示错误。适用小型脚本

    [root@VM-12-9-centos shell]# /bin/bash -v getNetWorkDataInfoError.sh 
    #!/bin/bash
    :<<!
    获取ip地址、掩码地址、广播地址、MAC地址
    !
    ifconfig docker0 | grep -w inet | tr -s " " | cut -d " "  -f 3 | xargs -I {} echo "IP: " {}
    IP:  172.17.0.1
    ifconfig docker0 | grep -w inet | tr -s " " | cut -d " "  -f 5 | xargs -I {} echo "Netmask: " {}
    Netmask:  255.255.0.0
    ifconfig docker0 | grep -w inet | tr -s " " | cut -d " "  -f 7 | xargs -I {} echo "Broadcast: " {}
    Broadcast:  172.17.255.255
    ifconfig docker0 | grep -w ether | tr -s " " | cut -d " "  -f 3 | xargs -I {} echo "MAC Address:  {}
    getNetWorkDataInfoError.sh:行8: 寻找匹配的 `"' 是遇到了未预期的文件结束符
    getNetWorkDataInfoError.sh:行9: 语法错误: 未预期的文件结尾
    

    -x 将执行的每条命令和执行结果都打印出来,适用复杂脚本

    [root@VM-12-9-centos shell]# /bin/bash -x getNetWorkDataInfoError.sh 
    + :
    + ifconfig docker0
    + grep -w inet
    + tr -s ' '
    + cut -d ' ' -f 3
    + xargs -I '{}' echo 'IP: ' '{}'
    IP:  172.17.0.1
    + ifconfig docker0
    + cut -d ' ' -f 5
    + tr -s ' '
    + xargs -I '{}' echo 'Netmask: ' '{}'
    + grep -w inet
    Netmask:  255.255.0.0
    + ifconfig docker0
    + xargs -I '{}' echo 'Broadcast: ' '{}'
    + grep -w inet
    + tr -s ' '
    + cut -d ' ' -f 7
    Broadcast:  172.17.255.255
    getNetWorkDataInfoError.sh:行8: 寻找匹配的 `"' 是遇到了未预期的文件结束符
    getNetWorkDataInfoError.sh:行9: 语法错误: 未预期的文件结尾
    
shell变量
  • 基本格式:$变量名 | "$变量名" | ${变量名} | "${变量名}"
  • 基础变量

    • 变量定义:

      • 变量包括:变量名 、变量值、赋值动作。
      • 格式:变量名=变量值 = 两边不允许有空格,因为空格代表两个命令的隔开
    • 类型变量定义:

      • 格式:declare 参数 变量名=变量值

      • 参数:

        • -i 定义为整数,类型不一致会出错
        • -r 该变量只能读
        • -x 定义为全局变量
        • -a 定义普通数组
        • -A 定义为关联数组
    • 变量的移除:

      • 格式:unset 变量名
  • 本地变量

    • 变量名仅仅在当前终端使用

    • 变量分类:

      • 普通变量:变量名=变量值

      • 格式:

        • 变量名=变量值 变量值必须是一个整个
        • 变量名='变量值' 原样输出
        • 变量名="变量值" 如果变量值中存在其它变量可以先进行解析然后赋值给新的变量名
      • 命令变量:通过命令将结果赋值给变量名 变量名=命令

      • 格式:

        1.变量名=`命令`
        [root@VM-12-9-centos shell]# name=`/bin/bash getNetWorkDataInfo.sh`
        [root@VM-12-9-centos shell]# echo $name 
        IP: 172.17.0.1 Netmask: 255.255.0.0 Broadcast: 172.17.255.255 MAC Address: 02:42:89:d8:ad:302.变量名=$(命令)
        [root@VM-12-9-centos shell]# name=$(/bin/bash getNetWorkDataInfo.sh)
        [root@VM-12-9-centos shell]# echo $name 
        IP: 172.17.0.1 Netmask: 255.255.0.0 Broadcast: 172.17.255.255 MAC Address: 02:42:89:d8:ad:30
        
  • 全局变量

    • 变量名能够在当前操作系统中的所有终端使用

      • 查看全局变量:env printenv export declare -x
    • 变量文件:创建在用户范围的只能自己查看,创建在系统范围的可以在多个用户查看

      • 用户范围:

        ./bashrc
        ./bash_profile
        
      • 系统范围:

        /etc/profile
        /etc/profile.d/env_file_name
        
  • 内置变量

    • 脚本相关内置变量

      变量名解释
      $0获得当前执行shell脚本的名称
      $n获得当前执行脚本的第n个参数,如果n大于10用大括号包裹起来${10}
      $#获得当前shell命令行中参数的总个数
      $?获得上一条命令执行的返回值(0为成功,非0代表失败)
    • 字符串相关内置变量

      length:
      ${#字符串}  获取字符串的长度
      [root@VM-12-9-centos shell]# name="zhangsan"
      [root@VM-12-9-centos shell]# echo ${#name}
      8
      
      split${字符串:索引起始位置:截取的个数}
      [root@VM-12-9-centos shell]# echo ${name:0:5}
      zhang
      
    • 默认值内置相关变量

      格式一:${变量值:-默认值}  如果变量值有值,则输出变量值,如果没有则输出默认值
      [root@VM-12-9-centos shell]# echo ${name:-lisi}
      zhangsan
      
      格式二:${变量值:+默认值}  无论变量值是否有值都输出默认值
      [root@VM-12-9-centos shell]# echo ${name:+lisi}
      lisi
      
    • 其它内置相关变量

      变量名解释
      $_在次之前执行命令或脚本的第一个内容:/bin/bash text.sh arg1 ,即这里的/bin/bash
      $@获取所有传递的参数
      $*以单字符串显示向脚本里传递的参数
      $$显示当前执行脚本的进程ID
      $!显示上一条命令进程的ID
      [root@VM-12-9-centos shell]# /bin/bash getNetWorkDataInfo.sh docker0 ent1 ent2
      IP:  172.17.0.1
      Netmask:  255.255.0.0
      Broadcast:  172.17.255.255
      MAC Address:  02:42:89:d8:ad:30
      
      docker0 ent1 ent2
      docker0 ent1 ent2
      13487
      
内容格式化
  • 常用符号解读

    • 重定向

      > 将符号左边的内容覆盖传递给符号右边的内容
      < 将符号右边的内容覆盖传递给符号左边的内容
      >> 将符号左边的内容追加传递给符号右边的内容
      << 将符号右边的内容追加传递给符号左边的内容
      
    • 管道符

      | 将左侧的内容传递给右侧
      
    • 后台执行

      命令 & 前台执行的命令放到后台执行 
      
    • 信息符号

      1 正确输出 示例:echo "zhangsan" 1> stand1.txt &
      2 错误输出 示例:echo1 "zhangsan" 2> standerror.txt &
      2>&1 全部输出 示例:echo "zhangsan" | echo1 123 > standout.txt 2>&1 &
      
  • 输入格式化

    • EOF 将文件内容按原格式输入到另外一个文件

      #!/bin/bash
      cat > file.txt << EOF 
      你好:
              您吃了吗?
                      -- 2022/02/22
      ​
      EOF
      

      需要注意的是:结尾的EOF需要顶格

    • tee 跟 重定向具有相同功能,同时还支持标准输出到多个文件

      [root@VM-12-9-centos shell]# cat <<EOF | sudo tee /usr/local/shell/a.txt
      > 
      > 标准输出:
      > EOF
      ​
      标准输出:
      
  • 输出格式化

脚本交互
  • 基础知识
  • 脚本内交互
  • 脚本外交互
shell表达式
  • 运算符表达式
  • 表达式实践
数组操作
  • 基础操作
  • 综合实践

二、流程控制

流程控制基础
条件控制
循环控制
过程控制
功能函数
自动化

三、进阶知识

正则表达式
sed命令
awk命令
脚本进阶

四、代码发布

代码发布基础
手工代码发布
简单脚本实践
大型脚本实践
脚本编写技巧