Loading

3-Shell

shell简介

  • 把在终端运行的命令保存到文件中,这个文件就是shell程序,简单的说,shell编程就是Linux命令的逻辑化处理
  • shell解释器
    • bash,ash,ksh,sh等,默认使用bash
    • echo $SHELL
      • /bin/bash
  • 内核<shell<应用程序

shell程序

  • 扩展名.sh(非必须)
  • #!/bin/bash
    • 指定解释器
  • 运行
    • 作为可执行程序
      • 先修改执行权限
      • ./test.sh
      • /root/test.sh
    • 作为解释器参数
      • 先修改执行权限
      • /bin/bash test.sh

shell变量

  • 命名规则

    • 只能使用数字字母下划线,不能以数字开头
    • 不能使用bash里的关键字
  • 变量定义

    • name="sicong"
      echo $name
      num=10
      echo ${num}
      
      • 变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界
  • 只读变量

    • readonly my_url
    • 只读变量的值不能发生改变
      • 下次登录清空
  • 删除变量

    • unset my_url
    • unset 命令不能删除只读变量

字符串和数组

  • 字符串

    • 单引号/双引号

      • 单引号中的任何字符都会原样输出,单引号字符串中的变量是无效的,两层单引号则还原
      • 双引号:可以包含除了$、`、\、‘‘之外的任意字符
      • 反斜线:转义特定的字符,如:&、*、^、等
    • 拼接字符串

      • my_name="sicong"
        str1="hello, "$my_name" !"
        str2="hello, ${my_name} !"
        
        • 注意str2必须使用双引号
    • 获取字符串长度

      • str="abcdef"
        echo ${#str}
        
    • 获取子字符串

      • str="1000phone is a good school"
        echo ${str:1:3}
        
        • 从下标1开始,长度为3,起始下标为0
  • 数组

    • 规则

      • bash只支持一维数组,不支持多维数组,并不限制数组的大小,数组中元素的下标从0开始
    • 定义数组

      • 数组名=(值1 值2 值3....)
    • 读取数组中的元素

      • \#读取数组中的元素
        echo ${arr1[2]}
        \#如果要读取数组中的全部元素
        echo ${arr2[@]}
        \#或
        echo ${arr2[*]}
        
      • 注意{}的使用

    • 获取数组元素的个数

      • length=${#arr1[@]}
        echo $length
        \# 或者
        length=${#arr1[*]}
        echo $length
        
    • 获取数组单个元素的长度

      • lengthn=${#arr1[3]}
        echo $lengthn
        

运算符

  • expr

    • expr:是一款表达式计算工具,使用它能够完成表达式的求值操作
  • 运算符

    • 数值运算符

      • + - * / %
        • val=expr 1 + 2
          • 注意``内各个字符间的空格
    • 文件测试

      • -r file  可读
        -w file  可写
        -x file  可执行
        -e file  是否存在
        -s file 检测文件是否为空
        -f file 是一个普通文件,并且有内容
        -z 变量名 判断变量名是空字符串或者没有定义过
        ! 取反 
        ! -z name 变量name的字符串长度非0
        
    • 关系运算符

      • []中,前后都需要空格
      • -eq
        • 数字相等
      • -ne
        • 数字不等
      • -gt
        • 大于
      • -lt
        • 小于
      • -ge
        • 大于等于
      • -le
        • 小于等于
      • ==
        • 字符串相等
          • if [ $a == $b ] # 字符串相等
    • 逻辑运算符

      • && || !
        • 与或非
      • if [ 1 -lt 3 ] && [ 2 -lt 3 ];

echo/printf/test命令

  • echo
    • 字符串的输出
      • echo -e "OK! \n"
        • -e 开启转义,\n 显示换行
      • echo -e "OK! \c"
        • -e 开启转义 \c 不换行
  • printf
    • printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等
    • printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
      printf "%-10s %-8s %-4.2f\n" 思聪 男 65.4321
      • %s %d %f都是格式替换符
      • -10s:指的是一个宽度为10的字符(-表示左对齐,没有则表示右对齐)
  • test
    • test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试
      • 注意与[]的联系
    • if test $[num1] -eq $[num2]

shell中的流程控制语句

  • if语句

    • 单分支

      • if [ 1 -lt 3 ] && [ 2 -lt 3 ]; 
        then
        	echo "ok"
        fi
        
      • 注意if后的分号

    • 双分支

      • else
    • 多分支

      • elif
        else
  • case语句

    • echo '输入 1 到 4 之间的数字:'
      read aNum
      case $aNum in
          1)  echo '你选择了 1'
          ;;
          2)  echo '你选择了 2'
          ;;
          3)  echo '你选择了 3'
          ;;
          4)  echo '你选择了 4'
          ;;
          *)  echo '你没有输入 1 到 4 之间的数字'
          ;;
      esac
      
  • 循环语句

    • for循环
      • for 条件
        do
        循环体
        done
    • for num in 1 2 3 4 5
    • for x in $
    • for i in $(cat a.txt)
      • 一行
    • for n in
  • while循环

    • while read line
      do
      echo $line
      done < /path/to/file
    • 注意传值的方式

函数

  • 无参数无返回值

    • demo()
      {
      	    echo 'hello world'
      }
      #调用函数
      demo
      
  • 有返回值

    • return \(((\)aNum+\(anotherNum)) \#用\)?接收
    • 注意双括号
  • 有参数有返回值

    • arg 3 4
    • 函数内$1表示参数1,$0表示程序名本身
    • $#
      • 传递到脚本的参数个数
    • $*
      • 与$@用法类似
    • 用echo $?接收返回值

扩展

  • #source hello.sh 将代码读入父shell直接执行
    或. hello.sh
    相当于python中的import

  • 关联数组

    • 类似python的字典

    • declare -A arr2=([name]=lotuslaw)
       echo ${arr2[name]}
      arr2[age]=10  # 赋值
      
  • echo $?

    • #如果返回值为0,说明上一条执行成功
  • if [[ "$num" =~ [0-9]+ ]];then

    • 注意使用正则匹配时,变量要用双引号
    • 条件判断使用正则,用[[]]
    • =~为匹配的意思
  • if [ -r $a.txt ]

  • if test -r a.txt

  • n=$(expr $n + 1)

    • 循环赋值
  • $(( n + 1 ))

    • 双层括号,内部变量无需加$
  • sh -x test.sh调试代码

  • ctrl v shift i esc

  • ping -c 2 www.baidu.com
    echo $?

    • 返回两次
  • awk

    • awk 模式 动作
      • 模式可以使用正则,在'//'内部
    • echo $i |awk -F'[ /]+' '/inet/ && $3 !~ /^127/ {print $3}'
    • awk -F: '/^root/,/adm/ {print $0}' /etc/passwd
    • $NF表示被分割的最后一个字段
    • # -v让awk使用shell变量
      # unip 只对连续重复的值进行处理
  • 命令 2>/dev/null 1>a.txt

    • 1表示标准正确输出
    • 2表示标准错误输出
    • 命令 &>/dev/null
  • vim末行模式

    • :%s/待替换/替换/g
      • g表示全局替换
  • sed

    • sed 's/待替换/替换/g' passwd
      • 交互,源文件不变
    • sed -i 's/待替换/替换/g' passed
      • 非交互,直接改变源文件
posted @ 2021-05-23 16:35  lotuslaw  阅读(50)  评论(0编辑  收藏  举报