• Shell基本语法及示例


    Shell的运行

    使用文件头

    加入文件头#!/bin/bash

    $ chmod +x $script_name

    $ ./$script_name

    Sh命令

    $ sh $script_name

    注:运行失败提示找不到文件时,请检查文件格式是否是UNIX格式,可通过notepad++中

    编辑->文档格式转换改变文档格式,或者使用vi编辑器中的set ff=unix命令

    脚本传参

    我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,$0 为执行的文件名,$1 为执行脚本的第一个参数,$2 为执行脚本的第二个参数,以此类推……

    参数

    说明

    $#

    传递到脚本的参数个数

    $*

    以一个单字符串显示所有向脚本传递的参数。
    如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。

    $$

    脚本运行的当前进程ID号

    $!

    后台运行的最后一个进程的ID号

    $@

    与$*相同,但是使用时加引号,并在引号中返回每个参数。
    如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。

    $-

    显示Shell使用的当前选项,与set命令功能相同。

    $?

    显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

    脚本内容:

    echo "Shell 传递参数实例!";

    echo "第一个参数为:$1";

    echo "参数个数为:$#";

    echo "传递的参数作为一个字符串显示:$*";

    echo "-- $* 演示 ---"

    for i in "$*"; do

        echo $i

    done

    echo "-- $@ 演示 ---"

    for i in "$@"; do

        echo $i

    done

    输出:

    Shell 传递参数实例!

    脚本路径为:./test.sh

    第一个参数为:1

    参数个数为:4

    传递的参数作为一个字符串显示:1 2 3 4

    -- $* 演示 ---

    1 2 3 4

    -- $@ 演示 ---

    1

    2

    3

    4

    输出重定向

    大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。

    重定向命令列表如下:

    命令

    说明

    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 之间的内容作为输入。

    注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

    /dev/null 文件

    /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。

    如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:

    $ command > /dev/null

    如果希望屏蔽同时 stdout 和 stderr,可以这样写:

    $ command > /dev/null 2>&1

    变量、数组和字符串

    声明

    变量名和等号之间不能有空格,命名须遵循如下规则:

    1. 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
    2. 中间不能有空格,可以使用下划线(_)。
    3. 不能使用标点符号。
    4. 不能使用bash里的关键字(可用help命令查看保留关键字)。

    有效的变量名:

    RUNOOB

    LD_LIBRARY_PATH

    _var

    var2

    直接在for循环中声明:

    for file in `ls /etc`

    for file in $(ls /etc)

    引用

    ${var_name} 或 $var_name

    强烈建议只使用前一种方式,避免出错

    字符串

    可使用单引号和双引号表示,但需要注意自个的区别:

    1. 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
    2. 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
    3. 双引号里可以有变量
    4. 双引号里可以出现转义字符

    拼接字符串

    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

    输出

    hello, runoob ! hello, runoob !

    hello, runoob ! hello, ${your_name} !

    获取字符串长度

    string="abcd"

    echo ${#string} #输出 4

    查找子字符串

    string="runoob is a great site"

    echo `expr index "$string" io`  # 输出 4 #

    查找字符i或 o的位置(哪个字母先出现就计算哪个)

     

    字符串提取

    假设有变量 var=http://www.aaa.com/123.htm.

    1. # 号截取,删除左边字符,保留右边字符。

    echo ${var#*//}

    其中 var 是变量名,# 号是运算符,*// 表示从左边开始删除第一个 // 号及左边的所有字符

    即删除 http://

    结果是 www.aaa.com/123.htm

    1. ## 号截取,删除左边字符,保留右边字符。

    echo ${var##*/}

    ##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的所有字符

    即删除 http://www.aaa.com/

    结果是 123.htm

    1. %号截取,删除右边字符,保留左边字符

    echo ${var%/*}

    %/* 表示从右边开始,删除第一个 / 号及右边的字符

    结果是:http://www.aaa.com

    1. %% 号截取,删除右边字符,保留左边字符

    echo ${var%%/*}

     %%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符

    结果是:http:

    1. 从左边第几个字符开始,及字符的个数

    echo ${var:0:5}

    其中的 0 表示左边第一个字符开始,5 表示字符的总个数。

    结果是:http:

    1. 从左边第几个字符开始,一直到结束。

    echo ${var:7}

    其中的 7 表示左边第8个字符开始,一直到结束。

    结果是 www.aaa.com/123.htm

    1. 从右边第几个字符开始,及字符的个数

    echo ${var:0-7:3}

    其中的 0-7 表示右边算起第七个字符开始,3 表示字符的个数。

    结果是:123

    1. 从右边第几个字符开始,一直到结束。

    echo ${var:0-7}

    表示从右边第七个字符开始,一直到结束。

    结果是:123.htm

    注:(左边的第一个字符是用 0 表示,右边的第一个字符用 0-1 表示)

     

    数组

    定义

    my_array=(A B C D)

    或通过索引定义

    array_name[0]=value0

    array_name[1]=value1

    array_name[2]=value2

    array_name[3]=value2

    数组遍历

    索引遍历

    echo "第一个元素为: ${my_array[0]}"

    echo "第二个元素为: ${my_array[1]}"

    echo "第三个元素为: ${my_array[2]}"

    echo "第四个元素为: ${my_array[3]}"

    全部元素

    echo "数组的元素为: ${my_array[*]}"

    echo "数组的元素为: ${my_array[@]}"

    获取数组长度

    echo "数组元素个数为: ${#my_array[*]}"

    echo "数组元素个数为: ${#my_array[@]}"

    条件判断

    数值测试

    参数

    说明

    -eq

    等于则为真

    -ne

    不等于则为真

    -gt

    大于则为真

    -ge

    大于等于则为真

    -lt

    小于则为真

    -le

    小于等于则为真

     

    字符串测试

    参数

    说明

    =

    等于则为真

    !=

    不相等则为真

    -z 字符串

    字符串的长度为零则为真

    -n 字符串

    字符串的长度不为零则为真

     

    文件测试

    参数

    说明

    -e 文件名

    如果文件存在则为真

    -r 文件名

    如果文件存在且可读则为真

    -w 文件名

    如果文件存在且可写则为真

    -x 文件名

    如果文件存在且可执行则为真

    -s 文件名

    如果文件存在且至少有一个字符则为真

    -d 文件名

    如果文件存在且为目录则为真

    -f 文件名

    如果文件存在且为普通文件则为真

    -c 文件名

    如果文件存在且为字符型特殊文件则为真

    -b 文件名

    如果文件存在且为块特殊文件则为真

    注:此类条件表达式固定写法必须使用中括号,且各项中间必须有空格

    num1=100

    num2=100

    if [ $[num1] -eq $[num2] ] ;then

    echo '两个数相等!'

    else

    echo '两个数不相等!'

    fi

    num1="ru1noob"

    num2="runoob"

    if [ $num1 = $num2 ] ;then

        echo '两个字符串相等!'

    else

        echo '两个字符串不相等!'

    fi

    if [ -e /bin/bash ] ;then

        echo '文件已存在!'

    else

        echo '文件不存在!'

    fi

    多重判断

    if [ condition1 ] ;then

        echo 1

    elif [ condition1 ] ;then

        echo 2

    else

        echo 3

    fi

    多重条件表达式

    [ condition1 ] || [ condition2 ]

    [ condition1 ] && [ condition2 ]

     

    循环

    For循环

    for num in 1 2 3 4 5

    do

        echo "The value is: $num"

    done

    for i in $(seq 1 5)

    do

        echo ${i}

    done

    my_array=(A B C D)

    for item in ${my_array[@]}

    do

    echo ${item}

    done

    for ((i=0;i<5;i++))

    do

      echo ${i}

    done

    While循环

    int=1

    while(( $int<=5 ))

    do

        echo $int

        let "int++"

    done

    使用了 Bash let 命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量,具体可查阅:http://www.runoob.com/linux/linux-comm-let.html

    Case、循环控制

    while :

    do

        echo -n "输入 1 到 5 之间的数字: "

        read aNum

        case $aNum in

            1|2|3) echo "你输入的数字为 $aNum!"

            ;;

            4)  echo '你输入了 4'

                continue

            ;;

            5)  echo '你输入了 5'

            ;;

            *)  echo "你输入的数字不是 1 到 5 之间的!"

                break

            ;;

        esac

    done

     

    函数

    定义

    注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

    函数返回值在调用该函数后通过 $? 来获得

    funWithReturn(){

        echo "这个函数会对输入的两个数字进行相加运算..."

        echo "输入第一个数字: "

        read aNum

        echo "输入第二个数字: "

        read anotherNum

        echo "两个数字分别为 $aNum 和 $anotherNum !"

        return $(($aNum+$anotherNum))}

    funWithReturn

    echo "输入的两个数字之和为 $? !"

    输出类似下面:

    这个函数会对输入的两个数字进行相加运算...

    输入第一个数字:

    1

    输入第二个数字:

    2

    两个数字分别为 1 和 2 !

    输入的两个数字之和为 3 !

     

    传参

    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

    输出结果:

    第一个参数为 1 !

    第二个参数为 2 !

    第十个参数为 10 !

    第十个参数为 34 !

    第十一个参数为 73 !

    参数总数有 11 个!

    作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !

    注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。

     

     

     

     

     

     

    特殊符号解释

    符号$后的括号

    ${a} 变量a的值, 在不引起歧义的情况下可以省略大括号。

    $(cmd) 命令替换, 结果为shell命令cmd的输出, 和`cmd`效果相同, 不过某些Shell版本不支持$()形式的命令替换, 如tcsh.

    $((exp)) 和`expr exp`效果相同, 计算数学表达式exp的数值, 其中exp只要符合C语言的运算规则即可, 甚至三目运算符和逻辑表达式都可以计算.

    多条命令执行

    (cmd1;cmd2;cmd3) 新开一个子shell顺序执行命令cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最后一个命令后可以没有分号.

    { cmd1;cmd2;cmd3;} 在当前shell顺序执行命令cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最后一个命令后必须有分号, 第一条命令和左括号之间必须用空格隔开.

    {}和()而言, 括号中的重定向符只影响该条命令, 而括号外的重定向符影响到括号中的所有命令.

    双括号的特殊用法

    (()) 增强括号的用法, 常用于算术运算比较. 双括号中的变量可以不使用$符号前缀, 只要括号中的表达式符合C语言运算规则, 支持多个表达式用逗号分开.

    比如可以直接使用for((i=0;i<5;i++)), 如果不使用双括号, 则为for i in `seq 0 4`或者for i in {0..4}.

    再如可以直接使用if (($i<5)), 如果不使用双括号, 则为if [ $i -lt 5 ].

    [[]] 增强方括号用法, 常用于字符串的比较. 主要用于条件测试, 双括号中的表达式可以使用&&, ||, <, >等C语言语法.

    比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果不适用双括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ].

    | 运算符

    管道符号,是unix一个很强大的功能,符号为一条竖线:"|"。

    用法:

    command 1 | command 2

    他的功能是把第一个命令command 1执行的结果作为command2的输入传给command 2,例如:

    $ls -s|sort -nr (请注意不要复制$符号进去哦)

    -s 是file size,-n是numeric-sort,-r是reverse,反转

    该命令列出当前目录中的文档(含size),并把输出送给sort命令作为输入,sort命令按数字递减的顺序把ls的输出排序。

    && 运算符:

    格式

    command1  && command2

    &&左边的命令(命令1)返回真(即返回0,成功被执行)后,&&右边的命令(命令2)才能够被执行;换句话说,“如果这个命令执行成功&&那么执行这个命令”。

    语法格式如下:

    command1 && command2 && command3 ...

    命令之间使用 && 连接,实现逻辑与的功能。

    只有在 && 左边的命令返回真(命令返回值 $? == 0),&& 右边的命令才会被执行。

    只要有一个命令返回假(命令返回值 $? == 1),后面的命令就不会被执行。

    例如 make && make install 表示编译成功后安装

  • 相关阅读:
    浏览器基础知识点及常考面试题
    java设计模式之综述
    maven的基本原理和使用
    maven的介绍和安装
    Spring整合Struts2的方法
    Spring整合Hibernate的方法
    Spring中的事务管理
    Spring中的JDBC操作
    基于XML配置的Sping AOP详解
    基于注解的Sping AOP详解
  • 原文地址:https://www.cnblogs.com/wp2ypy/p/10303149.html
Copyright © 2020-2023  润新知