Shell 语法

Posted kernel001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell 语法相关的知识,希望对你有一定的参考价值。


  •       Shell  之 语法

解释器:
1)Bourne Shell(/usr/bin/sh或/bin/sh)
2)Bourne Again Shell(/bin/bash)
3)C Shell(/usr/bin/csh)
4)K Shell(/usr/bin/ksh)
5)Shell for Root(/sbin/sh)

Shell 注释:
1. 单行注释
在一行的字符最前面加 #
2. 多行注释
:<<a
注释内容...
a

        a:
            a可以换成其他任意合法的符号
    eg:
        :<<EOF
        注释内容...
        注释内容...
        注释内容... 
        EOF

I/O:
输入:
read 变量 命令从标准输入中读取一行到变量中
输出:
echo 字符串 输出 echo 后面的内容(字符串)

    echo参数:
        -e      开启转义
    字符串:
        支持转义字符:
            \n  换行
            \c  不换行
    echo `命令`:
        打印命令执行后的结果

语法:
1. 变量
1)变量类型:
1)局部变量
2)环境变量
3)shell变量
$n 传入脚本的参数 $0 为脚本本身
$# 传递到脚本的参数个数
\(* 以一个单字符串显示所有向脚本传递的参数。 如"\)"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
\(@ 与\)
相同,但是使用时加引号,并在引号中返回每个参数。
如"$@"用「"」括起来的情况、以"$1" "\(2" … "\)n" 的形式输出所有参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
2)自定义变量
声明创建:
变量名=值
用法:
注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
1. 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
2. 中间不能有空格,可以使用下划线(_)。
3. 不能使用标点符号。
4. 不能使用bash里的关键字(可用help命令查看保留关键字)。
eg:
name="GAME"
只读变量:
readonly 变量名 在变量前加 readonly 命令
----> 将变量变为只读变量
----> 在变为只读变量时,应当初始化一下
使用变量:
1. $(var) --- 一般这样就可以
2. \((var) --- 加 只是区分变量边界 删除变量: unset 变量名 在变量前加 unset 注: 1. unset 不能删除 readonly变量 2. 变量删除后不能在再次使用 3)字符串 声明方法: 1> var='varValue' 2> var="varValue" 注: 1. 单引号 '' 方式的字符串,只视为字符串,不做其他处理 2. 双引号 "" 方式的字符串,可处理变量,转义字符 字符串拼接: "\)var1 \(var2" 引号内使用变量就是 '\)var \(var2' eg: your_name="runoob" # 使用双引号拼接 greeting="hello, "\)your_name" !"
greeting_1="hello, $your_name !"
echo $greeting $greeting_1

                # 使用单引号拼接
                greeting_2='hello, '$your_name' !'
                greeting_3='hello, $your_name !'
                echo $greeting_2  $greeting_3
        字符串长度:
            $#变量     字符串前加 # 字符
            eg:
            string="abcd"
            echo $#string #输出 4
        提取子字符串:
            变量:start:end    
                截取从start 到 end 位置的子字符串
            
            eg:
                string="runoob is a great site"
                echo $string:1:4 # 输出 unoo
        查找子字符串:
            eg:
                string="runoob is a great site"
                echo `expr index "$string" io`  # 输出 4
    4)数组
        数组定义:
            1)数组名=(值1 值2 ... 值n)
            2)数组名[下标]=值 等多个组成
        数组访问:
            $数组名[下标]
            
            注:
                1.下标n    是有效的数字
                2. @ 符号  获取所有元素
        数组长度:
            1. 取得所有长度       
                $#数组名[@或*]
            2. 取得数组单个元素的长度
                $#数组名[n]
                n 为下标
2. 运算符
    
    原生bash不支持简单的数学运算,但是可以通过其他命令来实现,
    例如 awk 和 expr,expr 最常用
    expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
    
    在以下的a,b分别为以下值
    a=10
    b=20
    算数运算符
        和 C 完全一样
        (+ - * / % = == !=)
    关系运算符
        关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
        -eq 检测两个数是否相等,相等返回 true。    [ $a -eq $b ] 返回 false。
        -ne 检测两个数是否不相等,不相等返回 true。  [ $a -ne $b ] 返回 true。
        -gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
        -lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
        -ge 检测左边的数是否大于等于右边的,如果是,则返回 true。   [ $a -ge $b ] 返回 false。
        -le 检测左边的数是否小于等于右边的,如果是,则返回 true。   [ $a -le $b ] 返回 true。
    布尔运算符
        !   非运算,表达式为 true 则返回 false,否则返回 true。  [ ! false ] 返回 true。
        -o  或运算,有一个表达式为 true 则返回 true。  [ $a -lt 20 -o $b -gt 100 ] 返回 true。
        -a  与运算,两个表达式都为 true 才返回 true。  [ $a -lt 20 -a $b -gt 100 ] 返回 false。
    逻辑运算符
        &&  逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
        ||  逻辑的 OR  [[ $a -lt 100 || $b -gt 100 ]] 返回 true
    字符串运算符
        假定变量 a 为 "abc",变量 b 为 "efg":
            =   检测两个字符串是否相等,相等返回 true。  [ $a = $b ] 返回 false。
            !=  检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
            -z  检测字符串长度是否为0,为0返回 true。  [ -z $a ] 返回 false。
            -n  检测字符串长度是否为0,不为0返回 true。 [ -n "$a" ] 返回 true。
            $   检测字符串是否为空,不为空返回 true。   [ $a ] 返回 true。
    文件测试运算符
        文件测试运算符用于检测 Unix 文件的各种属性。
            -b file 检测文件是否是块设备文件,如果是,则返回 true。  [ -b $file ] 返回 false。
            -c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
            -d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
            -f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。    [ -f $file ] 返回 true。
            -g file 检测文件是否设置了 SGID 位,如果是,则返回 true。  [ -g $file ] 返回 false。
            -k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。  [ -k $file ] 返回 false。
            -p file 检测文件是否是有名管道,如果是,则返回 true。   [ -p $file ] 返回 false。
            -u file 检测文件是否设置了 SUID 位,如果是,则返回 true。  [ -u $file ] 返回 false。
            -r file 检测文件是否可读,如果是,则返回 true。  [ -r $file ] 返回 true。
            -w file 检测文件是否可写,如果是,则返回 true。  [ -w $file ] 返回 true。
            -x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
            -s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
            -e file 检测文件(包括目录)是否存在,如果是,则返回 true。    [ -e $file ] 返回 true。
            
            -S: 判断某文件是否 socket。
            -L: 检测文件是否存在并且是一个符号链接。
3. 流程控制
    1) if...else
        单一判断:
            if condition
            then
                command1 
                command2
                ...
                commandN 
            fi
        多层判断:
            else、elif
        
        和C  语法差不多嵌套进去
    2) case
        case 值 in
        匹配1)
            command1
            command2
            ...
            commandN
            ;;
        匹配2)
            command1
            command2
            ...
            commandN
            ;;
        esac
        
    2) for 循环
        for var in item1 item2 ... itemN
        do
            command1
            command2
            ...
            commandN
        done
    3) while 循环
            while condition
            do
                command
            done
            
            eg:
                while(( $int<=5 ))
                do
                    echo $int
                    let "int++"
                done


    4)死循环
            while :
            do
                command
            done
        
        或者
        
            while true
            do
                command
            done
        
        或者
        
            for (( ; ; ))
    5) until 循环
            until condition
            do
                command
            done
            a=0
        
        eg:
            until [ ! $a -lt 10 ]
            do
               echo $a
               a=`expr $a + 1`
            done
    6) 跳出循环关键字:
        break   跳出循环
        continue    跳出本次循环
4. 函数
    [ function ] funname [()]

    

        action;

        [return int;]

    
    说明:
        1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
        2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
        3、函数返回值在调用该函数后通过 $? 来获得。
        
    函数传参:
        利用$n 的形式传参 $1第一个参数 $2 第二参数
        eg:
            funWithParam()
                echo "第一个参数为 $1 !"
                echo "第二个参数为 $2 !"
                echo "第十个参数为 $10 !"
                echo "第十个参数为 $10 !"
                echo "第十一个参数为 $11 !"
                echo "参数总数有 $# 个!"
                echo "作为一个字符串输出所有参数 $* !"
            
            funWithParam 1 2 3 4 5 6 7 8 9 34 73
            
        
5.命令
    输入、输出重定向:
        command > file  将输出重定向到 file。
        command < file  将输入重定向到 file。
        command >> file 将输出以追加的方式重定向到 file。
        n > file    将文件描述符为 n 的文件重定向到 file。
        n >> file   将文件描述符为 n 的文件以追加的方式重定向到 file。
        n >& m  将输出文件 m 和 n 合并。
        n <& m  将输入文件 m 和 n 合并。
        << tag  将开始标记 tag 和结束标记 tag 之间的内容作为输入。
        
        如果希望对 stdin 和 stdout 都重定向,可以这样写:
            $ command < file1 >file2
            command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2。
            
        Here Document:
          Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。
            
            它的基本的形式如下:
                command << delimiter
                    document
                delimiter
            它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
            注意:
            结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
            开始的delimiter前后的空格会被忽略掉。
            
            eg:
                $ wc -l << EOF
                    欢迎来到
                    菜鸟教程
                    www.runoob.com
                EOF
                3          # 输出结果为 3 行
                $
    printf:
        printf  format-string  [arguments...]
        参数说明:
            format-string: 为格式控制字符串
            arguments: 为参数列表。
            
            1)%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),
            任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,
            超过也会将内容全部显示出来。
            
            2)%-4.2f 指格式化为小数,其中.2指保留2位小数。
            
            \a  警告字符,通常为ASCII的BEL字符
            \b  后退
            \c  抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
            \f  换页(formfeed)
            \n  换行
            \r  回车(Carriage return)
            \t  水平制表符
            \v  垂直制表符
            \\  一个字面上的反斜杠字符
            \ddd    表示1到3位数八进制值的字符。仅在格式字符串中有效
            \0ddd   表示1到3位的八进制值字符
    test:
        Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
        
        数值测试:
            -eq 等于则为真
            -ne 不等于则为真
            -gt 大于则为真
            -ge 大于等于则为真
            -lt 小于则为真
            -le 小于等于则为真
            
            eg:
                num1=100
                num2=100
                if test $[num1] -eq $[num2]
                then
                    echo '两个数相等!'
                else
                    echo '两个数不相等!'
                fi
                
        字符串测试:
            =   等于则为真
            !=  不相等则为真
            -z 字符串  字符串的长度为零则为真
            -n 字符串  字符串的长度不为零则为真
            
        文件测试:
        -e 文件名  如果文件存在则为真
        -r 文件名  如果文件存在且可读则为真
        -w 文件名  如果文件存在且可写则为真
        -x 文件名  如果文件存在且可执行则为真
        -s 文件名  如果文件存在且至少有一个字符则为真
        -d 文件名  如果文件存在且为目录则为真
        -f 文件名  如果文件存在且为普通文件则为真
        -c 文件名  如果文件存在且为字符型特殊文件则为真
        -b 文件名  如果文件存在且为块特殊文件则为真
    
    文件包含:
            . filename   # 注意点号(.)和文件名中间有一空格

        或

            source filename

以上是关于Shell 语法的主要内容,如果未能解决你的问题,请参考以下文章

shell 基础语法

shell语法

推荐一个shell语法在线检查网站,也可以学习shell语法

推荐一个shell语法在线检查网站,也可以学习shell语法

shell编程之shell脚本语法

Shell与其命令语法分析