zoukankan      html  css  js  c++  java
  • Shell

    Shell的变量

    • 本地变量 生效范围为当前shell进程,对当前shell之外的其他shell进程 包括当前shell的子shell进程和父shell进程均无效。可以使用set查看当前所有变量
    • 环境变量 生效范围为当前shell进程及其子进程
      • 使用 export name=VALUEdeclare -x name=VALUE 创建或转换环境变量
    • 局部变量 生效范围为当前shell进程中某函数的作用范围中。使用local name=VALUE定义局部变量
    • 位置变量 用于执行脚本时传参
    • 特殊变量 shell内置的特殊变量

      • $0 获取脚本执行时的路径
      • $? 获取上一条指定的执行返回码
      • $* 把传递给脚本的所有参数 视为一个字符串
      • $@ 把传递给脚本的所有参数 每一个参数视为每一个独立的字符串
      • $# 传递给脚本的参数数量

      • $$ 获取当前shell的进程号

      • $! 获取执行的上一个指令的pid
      • $_ 获取上一个执行的命令或脚本的最后一个参数
    • 只读变量 只读变量不能被修改,不能unset销毁
      • readonly namedeclare -r name创建只读变量
    # 变量的引用
    [root@stardust ~]# echo $name
    [root@stardust ~]# echo ${name}
    
    
    # 命令结果引用
    [root@stardust ~]# echo `date` 
    [root@stardust ~]# echo $(date)
    
    
    # 销毁变量
    [root@stardust ~]# unset name

    Shell的算数运算

    shell默认不支持浮点运算,浮点运算需要使用awkbc

    [root@stardust ~]# let var=num1+num2        # let不会输出结果 需要复制给变量
    
    [root@stardust ~]# echo $[RANDOM%30]        # shell内置随机数生成器 1-32767
    
    [root@stardust ~]# echo $((2+3))
    
    [root@stardust ~]# expr 123 + 33 / 3 

    Shell条件判断

    条件测试

    • test EXPRESSION
    • [ EXPRESSION ]
    • [[ EXPRESSION ]]

    数值测试

    • -eq 等于
    • -ne 不等于
    • -lt 小于
    • -le 小于等于
    • -gt 大于
    • -ge 大于等于

    字符测试

    • ==/= 等值测试
    • != 不相等
    • =~ 左侧字符是否能被右侧的PATTERN所匹配 只能于[[ ]]中使用
    • -z "STRING" 若字符为空 为真
    • -n "STRING" 若字符串不为空 为真

    文件测试

    • -e 是否存在 不分类型
    • -s 是否存在且非空文件
    • -b 是否存在且为块设备
    • -c 是否存在且为字符设备
    • -f 是否存在且为普通文件
    • -d 是否存在且为目录
    • -S 是否存在且为套接字
    • -p 是否存在且为管道
    • -L -h 是否存在且为软链接文件
    • -g 是否存在且被设置了sgid
    • -u 是否存在且被设置了suid
    • -k 是否存在且被设置了sticky
    • -r 是否存在且可读
    • -w 是否存在且可写
    • -x 是否存在且可执行
    • -t fd 文件描述符是否打开且与某终端相关
    • -N 文件自上一次被读取后是否被修改(重定向写入)过
    • file1 -ef file2 判断两个文件是否指向同一个设备上的相同inode
    • file1 -nt file2 判断file1是否比file2时间戳更新
    • file1 -ot file2 判断file1是否比file2时间戳更旧

    逻辑运算

    • && -a
    • || -o
    • !

    Shell的语句

    if分支语句

    # 由上至下匹配,一旦匹配不再执行后面代码
    
    if CONDITION1; then
        COMMAND
    elif CONDITION2; then
        COMMAND
    esle
        COMMAND
    fi

    case分支语句

    # 由上至下匹配,一旦匹配不再执行后面代码
    # PAT部分不支持正则,但是支持glob机制 `*, ?, [], |`等
    
    case 变量引用 in
        PAT1|pat1)
            分支1
            ;;
        PAT2|pat2)
            分支2
            ;;
        *)
            默认分支
            ;;
    esac

    for循环语句

    # 列表生产方式
    #    [1] 直接给出列表 如 `a d c f`
    #    [2] 返回列表的命令 如`seq 10`,`ls *`
    #    [3] 变量引用 `$@, $*`
    #    [4] glob 如 `{1..10}`
    
    for 变量名 in 列表; do
        循环体
    done
    C语言型结构
    # 变量初始化仅在进入循环时执行一次
    # 每轮循环结束后会先进行变量修正运算,然后再进行条件判断
    
    for ((变量初始化;条件判断表达式;修正变量表达式)); do
        循环体
    done
    =======================================================================
    # demo 求100以内数字的和
    
    #!/bin/bash
    sum=0
    for ((i=1;i<101;i++));do
        ((sum=sum+i))
    done
    echo $sum
    简写结构
    # 正常结构中的"in 取值列表"可省略,省略时相当于`for n in "$@"`,循环列表为命令行参数列表
    
    # demo 打印传递给脚本的参数
    
    for VAR;do
        echo $VAR
    done
    [root@stardust ~]# sh test.sh  a b c d 
    a
    b
    c
    d

    while循环语句

    # 若条件为真 则一直执行循环体
    
    while CONDITION; do
        循环体
    done
    遍历文件内容
    # 通过输入重定向遍历文件
    while read VAR; do
        循环体
    done < /PATH/TO/FILE
    
    
    # 通过输出重定向遍历文件
    cat /PATH/TO/FILE | while read VAR; do
        循环体
    done
    
    
    # until同样支持此用法 不过需要取反`until ! read VAR`

    until循环语句

    # 若条件为假 则一直执行循环体
    
    until CONDITION; do
        循环体
    done

    Shell的函数

    # 语法一
    function FUNC_NAME {
        函数体
        return [N]
    }
    
    # 语法二
    FUNC_NAME() {
        函数体
        return [N]    
    }
    
    
    # return 返回自定义函数执行状态码,只能返回0-255之间的整数。
    # 如果没有显式的指定返回状态码,则返回函数最后一条指令的状态码
    
    
    # 函数的传参 `FUNC arg1 arg2…argN`
    # 函数参数的调用 在函数内 `$1 $2… $@ $*`

    Shell的数组

    能够存储多个元素的连续的内存空间

    # 定义数组
    ARRAY=(arg1 arg2 … argN)
    
    # 通过read创建数组
    read -a ARRAY
    
    # 打印整个数组
    echo ${ARRAY[*]}
    echo ${ARRAY[@]}
    
    # 数组的赋值与修改
    ARRAY[INDEX]=VALUE
    
    # 查看数组长度
    echo ${#ARRAY[*]}
    
    # 数组的删除
    unset ARRAY
    unset ARRAY[INDEX]
    
    # 数组的切片  N1为起始索引位置 N2为截取元素个数
    # N2可省略 表示截取到最后一个元素
    echo ${ARRAY[*]:N1:N2}
    
    # 打印数组最后N个元素
    echo ${ARRAY[*]: -N}
    
    # 数组元素的替换 使用的是变量子串操作
    echo ${ARRAY[*]/pat1/sub1}

    Shell的变量子串操作

    以下操作适用于字符串操作和数组操作。支持使用glob 如*,[],|

    变量切片和长度获取

    # `${#string}` 显示变量长度
    echo ${#string}
    
    # 变量的切片  N1为起始索引位置 N2为截取元素个数
    # N2可省略 表示截取到最后一个元素
    echo ${var:N1:N2}
    
    # 取最后N个元素 `-N`前必须有空格
    echo ${var: -N}

    变量删除替换操作

    # 测试字符串数据
    [root@stardust tools]# test=abcABC123abcABC
    
    # ${string#substring} 从string开头删除最短匹配字符串
    # ${string##substring} 从string开头删除最长匹配字符串
    [root@stardust tools]# echo ${test#a*c} 
    ABC123abcABC
    [root@stardust tools]# echo ${test##a*c}
    ABC
    
    # ${string%substring} 从string结尾删除最短匹配字符串
    # ${string%%substring} 从string结尾删除最长匹配字符串
    [root@stardust tools]# echo ${test%a*C} 
    abcABC123
    [root@stardust tools]# echo ${test%%a*C}
    ===========================================================================
    # 测试字符串数据
    [root@stardust tools]# test="root:x:0:0:root:/root:/bin/bash:root"
    
    # ${parameter/pattern/string} 替换第一个匹配的字符串
    [root@Stardust ~]# echo ${test/root/ROOT}                          
    ROOT:x:0:0:root:/root:/bin/bash:root
    
    # ${parameter//pattern/string} 替换所有匹配的字符串
    [root@Stardust ~]# echo ${test//root/ROOT}
    ROOT:x:0:0:ROOT:/ROOT:/bin/bash:ROOT
    
    # ${parameter/#pattern/string} 行首锚定 匹配开头第一个字段
    # ${parameter/%pattern/string} 行尾锚定 匹配结尾第一个字段
    
    # 以上多种形式`/string`部分可以省略 表示替换为空,即删除
    [root@Stardust ~]# echo ${test/root} 
    test::x:0:0:root:/root:/bin/bash:root
    
    [root@Stardust ~]# echo ${test//root} 
    test::x:0:0::/:/bin/bash:

    字符串大小写转换

    # 把所有字母转换为大写
    [root@Stardust ~]# echo ${var^^}
    
    # 把所有字母转换为小写
    [root@Stardust ~]# echo ${var,,}

    变量子串赋值

    # 如果变量为空或未设定, 返回default。存在则返回变量的值
    echo ${var:-default}
    
    # 如果变量为空或未设定, 给变量赋值默认值default
    echo ${var:=default}
    
    # 如果变量存在且非空则返回default。变量为空或未设定,不做任何操作。
    echo ${var:+default}
    
    # 如果变量为空或未设定, 返回错误信息
    echo ${var:?error_info}

    Shell的特殊关键字

    shift(变量左移)

    # `shift [N]` shift会将当前位置的变量销毁,并将后面位置的变量依次向前移动N位
    
    # 变量移位测试代码
    #!/bin/bash  
    while [ $# != 0 ]
    do  
        echo "第一个参数为:$1,参数个数为:$#"  
        shift  
    done  
    
    
    # 执行结果 $1在不断变化 变量数量在不断减少
    [root@stardust ~]# sh shift.sh a b c d e f g
    第一个参数为:a,参数个数为:7
    第一个参数为:b,参数个数为:6
    第一个参数为:c,参数个数为:5
    第一个参数为:d,参数个数为:4
    第一个参数为:e,参数个数为:3
    第一个参数为:f,参数个数为:2
    第一个参数为:g,参数个数为:1
    =======================================================================
    # 变量移位测试代码
    #!/bin/bash
    echo "变量个数 $#  变量为 $*"
    shift
    echo "变量个数 $#  变量为 $*"
    shift 2
    echo "变量个数 $#  变量为 $*"
    shift 3
    echo "变量个数 $#  变量为 $*"
    
    
    # 执行结果 第一次销毁1个变量 第二次销毁2个 第三次销毁3个
    [root@stardust ~]# sh shift_test.sh a b c d e f g
    变量个数 7  变量为 a b c d e f g
    变量个数 6  变量为 b c d e f g
    变量个数 4  变量为 d e f g
    变量个数 1  变量为 g

    read(命令行读入数据)

    # `read`支持指定多个形参 接收多个实参
    [root@stardust ~]# read arg1 arg2 arg3
    
    
    # `-p 'PROMPT'` 指定提示信息
    [root@stardust ~]# read -p "message:" arg1 arg2 arg3
    
    
    # `-t TIMEOUT` 设定超时时间
    [root@stardust ~]# read -t

    sh(调用shell解释器)

    [root@stardust ~]# sh -n        # 检查语法错误 不能检查出逻辑错误
    [root@stardust ~]# sh -x        # 调试执行

    exit(退出程序并返回状态码)

    • exit [N] 自定义退出状态码
    • 脚本中一旦遇到exit命令,脚本会立即终止。退出状态码取决于exit命令后面的数字
    • 如果脚本未给定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

    break(跳出循环)

    • break [N] 跳出循环
    • [N]代表层数,跳出N层循环

    continue(执行下一次循环)

    • continue [N] 提前结束循环 继续执行下一次循环
    • [N]代表层数,提前结束N层循环,继续执行下一次循环

    source(读取其他脚本内容)

    使用source.读取其他脚本内容,相当于python中的import

    • source /PATH/TO/FILE
    • . /PATH/TO/FILE




  • 相关阅读:
    浅谈观察者设计模式
    关于如何成为专家(1)
    微信小程序 PHP后端form表单提交实例详解
    mysql中的union和order by、limit
    SQL的各种连接(cross join、inner join、full join)的用法理解
    mysql数据库创建、删除数据库
    PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP 未声明(在此函数内第一次使用) 规格严格
    TroubleshootingGuide for JavaTM SE 6withHotSpot TM VM (翻译附录未完待续) 规格严格
    关闭URLClassLoader打开的jar包 规格严格
    两个长度分析【POST|GET】 规格严格
  • 原文地址:https://www.cnblogs.com/hemingyuan/p/7914444.html
Copyright © 2011-2022 走看看