Shell

Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
Shell 脚本(shell script),是一种为 shell 编写的脚本程序。
Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。
像 #!/bin/sh,它同样也可以改为 #!/bin/bash。

#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。
    chmod +x ./test.sh  #使脚本具有执行权限
    ./test.sh  #执行脚本

1.Shell 变量

    1.定义变量
        变量名不加美元符号($,PHP语言中变量需要)
        注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:

    2.使用变量
        使用一个定义过的变量,只要在变量名前面加美元符号即可

    3.只读变量
        使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

    4.删除变量

        使用 unset 命令可以删除变量
        变量被删除后不能再次使用。unset 命令不能删除只读变量。
2.变量类型

    运行shell时,会同时存在三种变量:

    1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,
                其他shell启动的程序不能访问局部变量。
    2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,
                有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
    3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有
            一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
3.Shell 字符串
    1. 单引号
        单引号字符串的限制:
    1.单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
    2.单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
    2.双引号
        双引号的优点:
    1.双引号里可以有变量
    2.双引号里可以出现转义字符
    3. 拼接字符串
        your_name="runoob"
        1.# 使用双引号拼接
            greeting="hello, "$your_name" !"
            greeting_1="hello, ${your_name} !"
            echo $greeting  $greeting_1
        2.# 使用单引号拼接
            greeting_2='hello, '$your_name' !'
            greeting_3='hello, ${your_name} !'
            echo $greeting_2  $greeting_3
        3.输出结果为:
            hello, runoob ! hello, runoob !
            hello, runoob ! hello, ${your_name} !
    4. 获取字符串长度
        string="abcd"
        echo ${#string} #输出 4
    5. 提取子字符串
        以下实例从字符串第 2 个字符开始截取 4 个字符:
        string="runoob is a great site"
        echo ${string:1:4} # 输出 unoo
4.Shell数组
    1. 定义数组
        在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:
        数组名=(值1 值2 ... 值n)
        例如:
        array_name=(value0 value1 value2 value3)
    2. 读取数组
        读取数组元素值的一般格式是:
        ${数组名[下标]}
        例如:
        valuen=${array_name[n]}
        使用 @ 符号可以获取数组中的所有元素,例如:
        echo ${array_name[@]}
    3. 获取数组的长度
        获取数组长度的方法与获取字符串长度的方法相同,例如:
        # 取得数组元素的个数
        length=${#array_name[@]}
        # 或者
        length=${#array_name[*]}
        # 取得数组单个元素的长度
        lengthn=${#array_name[n]}
5.Shell 注释
    1.以"#"开头的行就是注释,会被解释器忽略。
    2.sh里没有多行注释,只能每一行加一个#号。
    3.如果在开发过程中,遇到大段的代码需要临时注释起来,过一会儿又取消注释,怎么办呢?
        每一行加个#符号太费力了,可以把这一段要注释的代码用一对花括号括起来,
        定义成一个函数,没有地方调用这个函数,这块代码就不会执行,达到了和注释一样的效果。     
6.Shell 传递参数
    1.我们可以在执行 Shell 脚本时,向脚本传递参数,
        脚本内获取参数的格式为:$n。n 代表一个数字,
        1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
    2.几个特殊字符用来处理参数
        1.$#       传递到脚本的参数个数

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

        4.$!       后台运行的最后一个进程的ID号

        5.$@       与$*相同,但是使用时加引号,并在引号中返回每个参数。
                            如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
        6.$-       显示Shell使用的当前选项,与set命令功能相同。

        7.$?         显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
    3.$* 与 $@ 区别:
    相同点:都是引用所有参数。
    不同点:只有在双引号中体现出来。
            假设在脚本运行时写了三个参数 1、2、3,
                则 " * " 等价于 "1 2 3"(传递了一个参数),
                而 "@" 等价于 "1" "2" "3"(传递了三个参数)。
7.Shell 基本运算符
    1.Shell 和其他编程语言一样,支持多种运算符,包括:
    1.算数运算符
    2.关系运算符
    3.布尔运算符
    4.字符串运算符
    5.文件测试运算符
    2.算术运算符
        +     加法     `expr $a + $b` 结果为 30。
        -     减法     `expr $a - $b` 结果为 -10。
        *     乘法     `expr $a \* $b` 结果为  200。
        /     除法     `expr $b / $a` 结果为 2。
        %     取余     `expr $b % $a` 结果为 0。
        =     赋值     a=$b 将把变量 b 的值赋给 a。
        ==     相等。用于比较两个数字,相同则返回 true。     [ $a == $b ] 返回 false。
        !=     不相等。用于比较两个数字,不相同则返回 true。     [ $a != $b ] 返回 true。
    3.注意    
    1.表达式和运算符之间要有空格,例如 2+2 是不对的,
            必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
    2.完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,
            在 Esc 键下边。
        3.条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b] 是错误的,
            必须写成 [ $a == $b ]。
        4.乘号(*)前边必须加反斜杠(\)才能实现乘法运算;
    4.关系运算符
        1. 关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
             下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
            -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。
    5.布尔运算符
        1.下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
            !     非运算,表达式为 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。
    6.逻辑运算符
        以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
            &&     逻辑的 AND     [[ $a -lt 100 && $b -gt 100 ]] 返回 false
            ||     逻辑的 OR     [[ $a -lt 100 || $b -gt 100 ]] 返回 true
    7.字符串运算符
        下表列出了常用的字符串运算符,假定变量 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。

            str     检测字符串是否为空,不为空返回 true。             [ $a ]                返回 true。
    8.文件测试运算符
        文件测试运算符用于检测 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。
8.Shell echo命令
    1.显示普通字符串
        echo "It is a test"
        这里的双引号完全可以省略,以下命令与上面实例效果一致:
        echo It is a test
    2.显示转义字符
        echo "\"It is a test\""
        结果将是:
        "It is a test"
        同样,双引号也可以省略
    3.显示变量
        read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量
        #!/bin/sh
        read name
        echo "$name It is a test"
        以上代码保存为 test.sh,name 接收标准输入的变量,结果将是:
        [root@www ~]# sh test.sh
        OK                     #标准输入
        OK It is a test        #输出
    4.显示换行
        echo -e "OK! \n" # -e 开启转义
        echo "It it a test"
        输出结果:
        OK!
        It it a test
    5.显示不换行
        #!/bin/sh
        echo -e "OK! \c" # -e 开启转义 \c 不换行
        echo "It is a test"
        输出结果:
        OK! It is a test
    6.显示结果定向至文件
        echo "It is a test" > myfile
    7.原样输出字符串,不进行转义或取变量(用单引号)
        echo '$name\"'
        输出结果:
        $name\"
    8.显示命令执行结果
        echo `date`
        注意: 这里使用的是反引号 `, 而不是单引号 '。
        结果将显示当前日期
    read 命令一个一个词组地接收输入的参数,
        每个词组需要使用空格进行分隔;如果输入
        的词组个数大于需要的参数个数,则多出的词组
        将被作为整体为最后一个参数接收。

        测试文件 test.sh 代码如下:

        read firstStr secondStr
        echo "第一个参数:$firstStr; 第二个参数:$secondStr"

        执行测试:

        $ sh test.sh
        一 二 三 四
        第一个参数:一; 第二个参数:二 三 四

        实例, 文件 test.sh:

        read -p "请输入一段文字:" -n 6 -t 5 -s password
        echo -e "\npassword is $password"

        参数说明:

                -p 输入提示文字
                -n 输入字符长度限制(达到6位,自动结束)
                -t 输入限时
                -s 隐藏输入内容

        $ sh test.sh
        请输入一段文字:
        password is asdfgh

        muzhiming

             muzhiming

            muz***ing_zbq@163.com
        6个月前 (02-02)
9.Shell printf 命令
    1.printf 命令模仿 C 程序库(library)里的 printf() 程序。
        printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。
        printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,
                还可以制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添
                加换行符,我们可以手动添加 \n
                d: Decimal 十进制整数 -- 对应位置参数必须是十进制整数,否则报错!
                s: String 字符串 -- 对应位置参数必须是字符串或者字符型,否则报错!
                c: Char 字符 -- 对应位置参数必须是字符串或者字符型,否则报错!
                f: Float 浮点 -- 对应位置参数必须是数字型,否则报错!
            1.# format-string为双引号
                printf "%d %s\n" 1 "abc"
            2.# 单引号与双引号效果一样
                printf '%d %s\n' 1 "abc"
            3.# 没有引号也可以输出
                printf %s abcdef
            4.# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
                printf %s abc def
                printf "%s\n" abc def
                printf "%s %s %s\n" a b c d e f g h i j
            5.# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
                printf "%s and %d \n"
    2.printf的转义序列
        \a    警告字符,通常为ASCII的BEL字符
        \b    后退
        \c    抑制(不显示)输出结果中任何结尾的换行字符
            (只在%b格式指示符控制下的参数字符串中有效),而且,
                任何留在参数里的字符、任何接下来的参数以及任何留在
                格式字符串中的字符,都被忽略
        \f    换页(formfeed)
        \n     换行
        \r    回车(Carriage return)
        \t    水平制表符
        \v    垂直制表符
        \\    一个字面上的反斜杠字符
        \ddd     表示1到3位数八进制值的字符。仅在格式字符串中有效
        \0ddd    表示1到3位的八进制值字符
10.Shell test 命令
    Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
    1.数值测试
        -eq     等于则为真
        -ne     不等于则为真
        -gt     大于则为真
        -ge     大于等于则为真
        -lt     小于则为真
        -le     小于等于则为真
    2.字符串测试
        =     等于则为真
        !=     不相等则为真
        -z 字符串     字符串的长度为零则为真
        -n 字符串     字符串的长度不为零则为真
    3.文件测试
        -e 文件名     如果文件存在则为真
        -r 文件名     如果文件存在且可读则为真
        -w 文件名     如果文件存在且可写则为真
        -x 文件名     如果文件存在且可执行则为真
        -s 文件名     如果文件存在且至少有一个字符则为真
        -d 文件名     如果文件存在且为目录则为真
        -f 文件名     如果文件存在且为普通文件则为真
        -c 文件名     如果文件存在且为字符型特殊文件则为真
        -b 文件名     如果文件存在且为块特殊文件则为真
11.Shell 流程控制
    1.if else
        if condition1
        then
                command1
        elif condition2
        then
                command2
        else
                commandN
        fi
    2.if else语句经常与test命令结合使用
        num1=$[2*3]
        num2=$[1+5]
        if test $[num1] -eq $[num2]
        then
                echo '两个数字相等!'
        else
                echo '两个数字不相等!'
        fi
    3.for 循环
        for循环一般格式为:
        for var in item1 item2 ... itemN
        do
                command1
                command2
                ...
                commandN
        done
    4.while 语句
        while condition
        do
                command
        done
    5.until 循环
         until 循环执行一系列命令直至条件为 true 时停止。
         until 循环与 while 循环在处理方式上刚好相反    。
         until condition
            do
                    command
            done
         condition 一般为条件表达式,如果返回值为 false,
         则继续执行循环体内的语句,否则跳出循环。
    6.case
        case 值 in
        模式1)
                command1
                command2
                ...
                commandN
                ;;
        模式2)
                command1
                command2
                ...
                commandN
                ;;
        esac
        case工作方式如上所示。取值后面必须为单词in,每一模式必须以右括号结束。
            取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。
        取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他
            模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。
         esac
            case的语法和C family语言差别很大,它需要一个esac(就是case反过来)
                作为结束标记,每个case分支用右圆括号,用两个分号表示break
    7.跳出循环
        1.break命令
            break命令允许跳出所有循环(终止执行后面的所有循环)
        2.continue
            continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
12.Shell 函数
    1.[ function ] funname [()]
        {
                action;
                [return int;]
        }
        说明:
    1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
    2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,
            作为返回值。 return后跟数值n(0-255
        3.注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,
            直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
    2.函数参数
        在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,
        例如,$1表示第一个参数,$2表示第二个参数...
        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
        注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
        另外,还有几个特殊字符用来处理参数:
        参数处理     说明
        $#     传递到脚本的参数个数
        $*     以一个单字符串显示所有向脚本传递的参数
        $$     脚本运行的当前进程ID号
        $!     后台运行的最后一个进程的ID号
        $@     与$*相同,但是使用时加引号,并在引号中返回每个参数。
        $-     显示Shell使用的当前选项,与set命令功能相同。
        $?     显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
13.Shell 输入/输出重定向
    1.重定向命令列表
        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)。
    2.输出重定向
        command1 > file1
        上面这个命令执行command1然后将输出的内容存入file1。
        注意任何file1内的已经存在的内容将被新内容替代。
            如果要将新内容添加在文件末尾,请使用>>操作符。
    3.输入重定向
        和输出重定向一样,Unix 命令也可以从文件获取输入
        command1 < file1
        这样,本来需要从键盘获取输入的命令会转移到文件读取内容。
        注意:输出重定向是大于号(>),输入重定向是小于号(<)。
    4.重定向深入讲解
        一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
                标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
                标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
                标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
        默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。
    5./dev/null 文件
        如果希望执行某个命令,但又不希望在屏幕上显示输出结果,
            那么可以将输出重定向到 /dev/null:
        $ command > /dev/null
        /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;
            如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null
                文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。
        如果希望屏蔽 stdout 和 stderr,可以这样写:
        $ command > /dev/null 2>&1
            注意:0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
14.文件引用
    和其他语言一样,Shell 也可以包含外部脚本。
        这样可以很方便的封装一些公用的代码作为一个独立的文件。

        Shell 文件包含的语法格式如下:
        . filename   # 注意点号(.)和文件名中间有一空格
        或
        source filename
        实例
        创建两个 shell 脚本文件。
        test1.sh 代码如下:
        #!/bin/bash
        url="http://www.runoob.com"
        test2.sh 代码如下:
        #!/bin/bash
        # author:菜鸟教程
        # url:www.runoob.com
        #使用 . 号来引用test1.sh 文件
        . ./test1.sh
        # 或者使用以下包含文件代码
        # source ./test1.sh
        echo "菜鸟教程官网地址:$url"
        接下来,我们为 test2.sh 添加可执行权限并执行:
        $ chmod +x test2.sh
        $ ./test2.sh
        菜鸟教程官网地址:http://www.runoob.com
        注:被包含的文件 test1.sh 不需要可执行权限。

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值