Shell编程笔记

Shell编程笔记

created by cjk on 2019.4.14

一、Shell概述

  • Shell的定义:Shell是一个命令解释器,它接收应用程序/用户的命令,调用操作系统内核执行任务。

二、Shell解析器

  • 在Linux系统中,有多个Shell解析器,列表配置于/etc/shell文件中

  • 常用的解析器有两种:sh和bash,在centos中,sh是一个软连接指向bash,但是在一些系统中,sh也不是指向bash而是指向dash,如Debian和Ubuntu系统

  • 默认的Shell解析器:echo $SHELL

三、Shell脚本HelloWorld

  • 脚本的格式:以#!/bin/bash开头,用于指定使用哪个解析器解析脚本

  • 执行脚本时如果是使用命令调用,如sh test.sh或bash test.sh是不需要执行权限的,如果是直接使用./test.sh的方式运行脚本的话,需要用户对该文件有执行权限

四、Shell脚本多命令处理

  • 在实际使用过程中,Shell脚本通常是多个指令集组成的复杂功能。

五、Shell系统变量和自定义变量

  • 常用的系统变量

    $HOME    # 当前系统家目录
    $PWD    #当前脚本所在路径
    $SHELL    # 当前使用的shell解释器名称
    $USER    # 当前执行脚本的用户名称
    $MAIL    # 邮件保存路径
    $RANDOM    #生成一个随机数字
    $PATH    # 执行命令时搜索解释器的路径,相当于windows中的path环境变量
    
  • 如果需要查看所有已定义的系统变量,可以使用env命令查看

  • 自定义变量

    • 基本语法

      1. 定义变量
      A=12
      
      1. 撤销变量
      unset A
      
      1. 定义静态变量(只读变量),此变量不能被unset
      readonly B=3
      
      1. 将局部变量提升为全局变量,供其他shell程序使用
      A=66
      export A
      
  • 特殊变量

    1. $n:n代表数字,$0代表此脚本路径及名称,$1-$9代表第一到第九个参数,从第十开始需要用大括号包裹参数,如:${10},脚本的参数输入跟在执行命令后即可,以空格隔开

      • 基本语法
      #!/bin/bash
      echo "script_name: $0"
      echo "first_param: $1"
      echo "second_param: $2"
      
    2. $#:获取所有输入参数的个数,常用于循环中

      • 基本语法
      #!/bin/bash
      echo $#
      
    3. $*与$@:$*和$@在直接使用的情况下输出的内容一致,但是在"$*"与"$@"下,前者会把所有参数当成一个整体,后者会把每个参数都区分开来

    4. $?:最后一次执行的命令的返回状态,如果这个变量的值为0,证明上一个命令正确执行,如果为非0,则证明上一条命令执行不正确

      • 基本语法
      #!/bin/bash
      echo "success command"
      echo "command execute status: $?"    # 正确的返回值0
      pws    # 错误的不存在的命令
      echo "command execute status: $?"    # 错误的返回值127
      

六、Shell运算符

  • 整数运算:常用的整数运算符有$(())和$[]以及expr
#!/bin/bash
let S=(2+3)*5    # let运算符必须指定一个接收变量,然后才能用于输出
echo $S
echo $[(2+3)*5]    # $[]运算符可以很方便计算出四则表达式
echo $(((2+3)*5))    # $(())用法与$[]的一致,只是符号不同
echo $(expr $(expr 2 + 3) * 5)    # expr命令不支持括号优先运算,需要使用$()让需要的内容优先运算,且其乘号的表达式为*不能使用*,因为*默认为通配符
  • 浮点数运算:浮点运算可以通过bc命令来执行,需要注意的是,bc命令必须搭配echo命令取出运算值
#!/bin/bash
echo "$(echo "3.14*2" | bc)*10.0" | bc    # 这个表达式可以解析为先执行echo "3.14*2" | bc命令,得到结果6.28,然后执行echo 6.28*10 | bc命令得到最终运算结果62.8

七、Shell条件判断

  • 基本语法:[ condition ],注意[]前后都是有空格的,且条件非空即为true,如[ abc ]返回为true而[]返回为false

  • 常用判断条件

    1. 字符串之间的比较,使用 != 和 = 来进行判断,注意,条件判断符两边都是有空格的
    #!/bin/bash
    test="haha"
    [ "haha" = $test ]
    echo $?
    [ "haha" != $test ]
    echo $?
    
    1. 整数之间的比较

      • -lt:小于(less than)
      • -le:小于等于(less equal)
      • -eq:等于(equal)
      • -gt:大于(greater than)
      • -ge:大于等于(greater equal)
      • -ne:不等于(Not equal)
    #!/bin/bash
    [ 22 -lt 23 ]    #如果22是小于33的,那么判断会执行成功,$?返回为0,否则返回非零数
    [ $? -ne 0 ] && echo "22 ge 23" || echo "22 lt 23"
    [ 22 -le 22 ]
    [ $? -ne 0 ] && echo "22 gt 22" || echo "22 le 22"
    [ 33 -eq 22 ]
    [ $? -ne 0 ] && echo "33 ne 22" || echo "33 eq 22"
    [ 33 -gt 32 ]
    [ $? -ne 0 ] && echo "33 le 32" || echo "33 gt 32"
    [ 33 -ge 33 ]
    [ $? -ne 0 ] && echo "33 lt 33" || echo "33 ge 33"
    [ 22 -ne 33 ]
    [ $? -ne 0 ] && echo "22 eq 23" || echo "22 ne 33"
    
    1. 浮点数类型的比较
    [ $(echo "2.16>3.33" | bc) -eq 0 ] && echo "fail" || echo "success"
    # 利用bc指令返回是否为0来判断浮点数的大小,返回0说明表达式成立,返回1说明表达式不成立
    
    1. 文件权限判断

      • -r:有读的权限
      • -w:有写的权限
      • -x:有执行的权限
      • 值得注意的是,该判断方式不能区分是用户权限还是组权限,只要文件有该权限即返回True
      • 在root用户下执行判断除非是解除了文件的执行权限,解除文件读和写的权限似乎并没有用,判断依旧会返回True,实际上root用户即使解除了文件的所有权限,依旧是可以进行读和写的,这与文件权限的判断结果一致
    #!/bin/bash
    [ -x ./first.sh ] && echo "first file has execute permission" || echo "no execute permission"
    [ -w ./first.sh ] && echo "first file has write permission" || echo "no write permission"
    [ -r ./first.sh ] && echo "first file has read permission" || echo "no read permission"
    
    1. 文件类型判断

      • -f:文件是否存在且为一个常规的文件file
      • -e:文件存在,可以是文件也可以是目录existence
      • -d:文件存在,且是一个目录directory
    #!/bin/bash
    [ -f ./first.sh ] && echo "first.sh file exist" || echo "no such file named first.sh"
    [ -e ./first.sh ] && echo "first.sh file/dir exist" || echo "no file/dir named first.sh"
    [ -d ./first.sh ] && echo "first.sh dir exist" || echo "no such dir named first.sh"
    
  • Shell条件判断的小技巧

    • 在只有一层if else的情况,判断条件简单的情况下,可以使用判断表达式来代替if else
    [ -d ./first.sh ] && echo "first.sh dir exist" || echo "no such dir named first.sh"
    # 判断当前目录下是否存在first.sh的目录,如果存在,判断表达式[ -d ./first.sh ]将会输出True,因此会执行下一步的 && 操作运算符后面的内容,输出"first.sh dir exist",如果不存在,输出为false,由于与条件被短路就不会执行 && 后的内容了,而会去进一步执行 || 后的内容,利用这种方式就可以简单的达到条件判断的目的了。
    

八、其他注意点

  1. 等号赋值时不要习惯性地在两端加上空格,会报错
  2. Shell脚本中自定义变量的命名最好都以大写命名
  3. 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
  4. 变量的值如果有空格,需要使用双引号或者单引号包裹
原文地址:https://www.cnblogs.com/soundofcolors/p/11041002.html