• 【Linux开发基础知识】shell语法整理


    shell 常用语法整理

    shell 变量

    自定义变量

    变量定义 a=1
    变量引用 $a ${a}

    Makefile 中 对于Makefile 变量的引用 使用Makefile 下的方式$(a)
    对于shell 中的变量使用$${a}

    系统变量

    $0 		当前脚本的名称;
    $n 		当前脚本的第n个参数,n=1,2,…9;
    $* 		当前脚本的所有参数(不包括程序本身);
    $# 		当前脚本的参数个数(不包括程序本身);
    $? 		令或程序执行完后的状态,返回0表示执行成功;
    $$ 		程序本身的PID号。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    环境变量

    PATH  		命令所示路径,以冒号为分割;
    HOME  		打印用户家目录;
    SHELL 		显示当前Shell类型;
    USER  		打印当前用户名;
    ID    		打印当前用户id信息;
    PWD   		显示当前所在路径;
    TERM  		打印当前终端类型;
    HOSTNAME    显示当前主机名;
    PS1         定义主机命令提示符的;
    HISTSIZE    历史命令大小,可通过 HISTTIMEFORMAT 变量设置命令执行时间;
    RANDOM      随机生成一个 0 至 32767 的整数;
    HOSTNAME    主机名
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    流程控制

    if

    If条件判断语句,通常以if开头,fi结尾。也可加入else或者elif进行多条件的判断

    # 单分支语句 —比较大小
    if [条件表达式];then
    语句1
    fi
    # 双分支if 语句
    if [表达式)
    语句1
    else
    语句2
    fi
    # 多支条件语句 —判断成绩
    if [表达式]
    语句1
    elif
    语句2
    elif
    语句2
    fi

    常见逻辑判断
    -f 判断文件是否存在 eg: if [ -f filename ];
    -d 判断目录是否存在 eg: if [ -d dir ];
    -eq 等于,应用于整型比较 equal;
    -ne 不等于,应用于整型比较 not equal;
    -lt 小于,应用于整型比较 letter;
    -gt 大于,应用于整型比较 greater;
    -le 小于或等于,应用于整型比较;
    -ge 大于或等于,应用于整型比较;
    -a 双方都成立(and) 逻辑表达式 –a 逻辑表达式;
    -o 单方成立(or) 逻辑表达式 –o 逻辑表达式;
    -z 空字符串;
    -x 是否具有可执行权限
    -n 字符空判断
    || 单方成立;
    && 双方都成立表达式。

    例:判断程序是否在运行

    #!/bin/bash
    name=crond
    num=$(ps -ef|grep $name|grep -vc grep)
    if [ $num -eq 1 ];then
        echo "$num running!"
    else
        echo "$num is not running!"
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    for

    #格式:for name [ [ in [ word ... ] ] ; ] do list ; done
    for 变量名 in 取值列表; do
        语句 1
    done
    
    • 1
    • 2
    • 3
    • 4

    例:检测主机存活

    Network=$1
    for Host in $(seq 1 254)
    do
    ping -c 1 $Network.$Host > /dev/null && result=0 || result=1
    
    if [ "$result" == 0 ];then
      echo -e "\033[32;1m$Network.$Host is up \033[0m"
      echo "$Network.$Host" >> /tmp/up.txt
    
    else
      echo -e "\033[;31m$Network.$Host is down \033[0m"
      echo "$Network.$Host" >> /tmp/down.txt
    fi
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    while

    While循环语句与for循环功能类似,主要用于对某个数据域进行循环读取、对文件进行遍历,通常用于需要循环某个文件或者列表,满足循环条件会一直循环,不满足则退出循环,其语法格式以while…do开头,done结尾与

    while 关联的还有一个 until 语句,它与 while 不同之处在于,是当条件表达式为 false 时才循环,实际使用中比较少,这里不再讲解。
    
    while  (表达式)
    do
    语句1
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    #示例 1:在死循环中,满足条件终止循环
    while true; do
      let N++
      if [ $N -eq 5 ]; then
        break
    fi
      echo $N
    done
    输出: 1 2 3 4
    
    #示例 2:举例子说明 continue 用法
    N=0
    while [ $N -lt 5 ]; do
      let N++
    if [ $N -eq 3 ]; then
      continue
    fi
      echo $N
    done
    
    输出: 1 2 4
    
    # 打印 1-100 数字
    i=0
    while ((i<=100))
    do
            echo  $i
            i=`expr $i + 1`
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    case

    Case选择语句,主要用于对多个选择条件进行匹配输出,与if elif语句结构类似,通常用于脚本传递输入参数,打印出输出结果及内容,其语法格式以Case…in开头,esac结尾。语法格式如下:

    case 模式名  in
    模式 1)
        命令
        ;;
    模式 2)
        命令
        ;;
    *)
    不符合以上模式执行的命令
    esac
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    每个模式必须以右括号结束,命令结尾以双分号结束。

    例.

    while true
    do
        echo -e "
        \033[31m start \033[0m
        \033[32m stop \033[0m 
        \033[33m status \033[0m
        \033[34m quit \033[0m 
    "
    read -p "请输入你的选择start|stop|quit:" char
    case $char in
    start)
        systemctl start httpd && echo "httpd服务已经开启" || echo "开启失败"
    ;;
    stop)
        systemctl stop httpd && echo "httpd服务已经关闭" || echo "关闭失败"
    ;;
    restart)
        systemctl restart httpd && echo "httpd服务已经重启" || echo "重启失败
    "
    ;;
    status)
        systemctl status httpd && echo -e "
            httpd 的服务状态
    ;;
    quit)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    select

    #select 是一个类似于 for 循环的语句
    #Select语句一般用于选择,常用于选择菜单的创建,可以配合PS3来做打印菜单的输出信息,其语法格式以select…in do开头,done结尾:
    
    select i in (表达式) 
    do
    语句
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    例:选择mysql版本

    # 选择mysql 版本
    #!/bin/bash
    # by author rivers on 2021-9-27
    PS3="Select a number: "
    while true; do
    select mysql_version in 5.1 5.6 quit;
     do
      case $mysql_version in
      5.1)
        echo "mysql 5.1"
          break
          ;;
      5.6)
        echo "mysql 5.6"
           break
           ;;
      quit)
        exit
        ;;
      *)
        echo "Input error, Please enter again!"
          break
    esac
     done
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    shell 函数

    Shell允许将一组命令集或语句形成一个可用块,这些块称为Shell函数,Shell函数的用于在于只需定义一次,后期随时使用即可,无需在Shell脚本中添加重复的语句块,其语法格式以function name(){开头,以}结尾。

    Shell编程函数默认不能将参数传入()内部,Shell函数参数传递在调用函数名称传递,例如name args1 args2。

    函数语法

    func() {
    command1
    command1
    ……
    }
    fun # 直接调用函数名

    例:

    #!/bin/bash
    func() {
    VAR=$((1+1))
    return $VAR
    echo "This is a function."
    }
    func
    echo $?
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    字符

    字符串变量的创建

    1. 使用单引号创建:var=‘test’。
      这种方式创建的变量只能原样输出,变量无效,我们可以借用c中的“字符串常量”的定义理解这种特性。除此以外,单引号中不能出现单独的单引号,转义也是不可以的。
    2. 使用双引号创建:var=“my name is ${name}”,这种方式创建的字符串变量有效,也可以出现转义符。

    拼接字符串

    1. 字面量拼接
      str01="1""2"或者str01=“1”‘2’,这样就将1和2两个字符拼接在了一起。需要注意的是两个串之间不可以有空格。
    2. 变量拼接
      str03=${part01}${part02}或str04=${part01}“end"或str05=”${part01} ${part02}"这三种方式都可以拼接字符串变量。
    3. 命令拼接
      str02= date“end”,这里的date是一个shell命令,需要使用引用,具体如下:

    提取子字符串

    代码意义
    ${varible##*string}从左向右截取最后一个string后的字符串
    ${varible#*string}从左向右截取第一个string后的字符串
    ${varible%%string*}从右向左截取最后一个string后的字符串
    ${varible%string*}从右向左截取第一个string后的字符串
    ${varible:n1:n2}截取变量varible从n1到n2之间的字符串,可以根据特定字符偏移和长度,来选择特定子字符串

    运算符

    关系运算符

    运算shell中的实现主要符号
    检测两个数是否相等[ $a -eq $b ]-eq
    检测两个数是否不相等[ $a -ne $b ]-ne
    检测左边的数是否大于右边的[ $a -gt $b ]-gt
    检测左边的数是否小于右边的[ $a -lt $b ]-lt
    检测左边的数是否大于等于右边的[ $a -ge $b ]-ge
    检测左边的数是否小于等于右边的[ $a -le $b ]-le

    字符串运算符

    运算shell中的实现主要符号
    检测两个字符串是否相等[ $a = $b ]=
    检测两个字符串是否不相等[ $a != $b ]!=
    检测字符串长度是否为0[ -z $a ]-z
    检测字符串长度是否不为 0[ -n “$a” ]-n
    检测字符串是否为空[ $a ]$

    文件测试运算符

    文件测试运算符
    主要用于检测unix文件的各种属性:

    运算shell中的实现主要符号
    检测文件是否是块设备文件[ -b $file ]-b file
    检测文件是否是字符设备文件[ -c $file ]-c file
    检测文件是否是目录[ -d $file ]-d file
    检测文件是否是普通文件(既不是目录,也不是设备文件)[ -f $file ] 返回 true-f file
    检测文件是否设置了 SGID 位[ -g $file ]-g file
    检测文件是否设置了粘着位(Sticky Bit)[ -k $file ]-k file
    检测文件是否是有名管道[ -p $file ]-p file
    检测文件是否设置了 SUID 位[ -u $file ]-u file
    检测文件是否可读[ -r $file ]-r file
    检测文件是否可写[ -w $file ]-w file
    检测文件是否可执行[ -x $file ]-x file
    检测文件是否为空(文件大小是否大于0)[ -s $file ]-s file
    检测文件(包括目录)是否存在[ -e $file ]-e file

    数组

    定义数组

    数组名=(元素1 元素2 元素3 … 元素n)

    赋值数组

    数组名[下标]=值

    使用数组

    ${数组名[下标]}

    例:遍历数组

    #!/bin/bash
    a=(1 2 3 4 5 6)
    for((i=0; i<10; i++))
    do
        echo "a[$i]=${a[$i]}"
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    获取数组长度

    我们可以使用#来获取数组长度,需要注意的是在shell脚本中我们越界访问数组时是不会报错的。

    #!/bin/bash
    a=(1 2 3 4 5 6)
    echo ${a[*]}
    echo "a len: ${#a[*]}"
    
    • 1
    • 2
    • 3
    • 4

    合并数组

    #!/bin/bash
    a=(1 2 3 4 5 6)
    b=("hello" "zhaixue.cc")
    c=(${a[*]} ${b[*]})
    
    • 1
    • 2
    • 3
    • 4

    删除数组元素

    #!/bin/bash
    a=(1 2 3 4 5 6)
    echo ${a[*]}
    echo "a len: ${#a[*]}"
    unset a[5]
    echo ${a[*]}
    echo "a len: ${#a[*]}"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    Nginx内存池(内存池重置函数)
    【Web开发】纯前端实现科技企业官网首页
    MySQL高级语句 Part2(视图表 +存储过程+条件语句+循环语句)
    gin框架再探
    【USRP】通信之射频与微波通信
    前端笔记:使用Proxy实现响应式和双向数据绑定
    MySQL查询性能优化七种硬核之索引下推
    Cloudreve搭建云盘系统,并实现随时访问
    【数据库学习】图数据库:neo4j
    5. 树的存储结构:【双亲表示法、孩子表示法、孩子兄弟表示法】+【树、森林和二叉树的转换】
  • 原文地址:https://blog.csdn.net/yy197696/article/details/126186929