• Linux Shell学习


    1.Shell

    shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁。用户的大部分工作都是通过Shell完毕的。

    Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和运行用户输入的命令。作为程序设计语言,它定义了各种变量和參数,并提供了很多在高级语言中才具有的控制结构,包含循环和分支。


    2.Shell有两种运行命令的方式:

    • 交互式(Interactive):解释运行用户的命令,用户输入一条命令,Shell就解释运行一条。
    • 批处理(Batch):用户事先写一个Shell脚本(Script),当中有非常多条命令。让Shell一次把这些命令运行完,而不必一条一条地敲命令。
    Shell脚本和编程语言非常相似,也有变量和流程控制语句,但Shell脚本是解释运行的,不须要编译,Shell程序从脚本中一行一行读取并运行这些命令。相当于一个用户把脚本中的命令一行一行敲到Shell提示符下运行。


    3.bash全然兼容sh。也就是说,用sh写的脚本能够不加改动的在bash中运行。

    4.Shell支持自己定义变量。

    定义变量时,变量名不加美元符号($),如:

    1. variableName="value"
    注意,变量名和等号之间不能有空格(两側都不能够有空格)。这可能和你熟悉的全部编程语言都不一样。同一时候,变量名的命名须遵循例如以下规则:
    • 间不能有空格,能够使用下划线(_)。

    • 不能使用标点符号。
    • 不能使用bash里的keyword(可用help命令查看保留keyword)。 

    5.使用一个定义过的变量,仅仅要在变量名前面加美元符号($)就可以,如:

    
    
    1. your_name="mozhiyan"
    2. echo $your_name
    3. echo ${your_name}}
    变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界。比方以下这样的情况:
    
    
    1. for skill in Ada Coffe Action Java
    2. do
    3. echo "I am good at ${skill}Script"
    4. done
    假设不给skill变量加花括号,写成echo "I am good at $skillScript",解释器就会把$skillScript当成一个变量(其值为空),代码运行结果就不是我们期望的样子了。

    推荐给全部变量加上花括号,这是个好的编程习惯。

    6.仅仅读变量

    使用 readonly 命令能够将变量定义为仅仅读变量,仅仅读变量的值不能被改变。

    以下的样例尝试更改仅仅读变量,结果报错:
    1. #!/bin/bash
    2.  
    3. myUrl="http://see.xidian.edu.cn/cpp/shell/"
    4. readonly myUrl
    5. myUrl="http://see.xidian.edu.cn/cpp/danpianji/"
    执行脚本,结果例如以下:
    /bin/sh: NAME: This variable is read only.

    7.删除变量

    使用 unset 命令能够删除变量。语法:
    1. unset variable_name
    变量被删除后不能再次使用;unset 命令不能删除仅仅读变量。

    8.算术运算符

    1. if [ $a == $b ]
    2. then
    3. echo "a is equal to b"
    4. fi
    注意:条件表达式要放在方括号之间,而且要有空格,比如 [$a==$b] 是错误的,必须写成 [ $a == $b ]。

    乘号(*)前边必须加反斜杠()才干实现乘法运算
    算术运算符列表
    运算符 说明 举例
    + 加法 `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。



    9.关系运算符

    关系运算符仅仅支持数字,不支持字符串,除非字符串的值是数字。

    关系运算符列表
    运算符 说明 举例
    -eq 检測两个数是否相等。相等返回 true。 [ $a -eq $b ] 返回 true。
    -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。



    10.布尔运算符

    布尔运算符列表
    运算符 说明 举例
    ! 非运算,表达式为 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。


    11.字符串运算符

    字符串运算符列表
    运算符 说明 举例
    = 检測两个字符串是否相等,相等返回 true。

    [ $a = $b ] 返回 false。
    != 检測两个字符串是否相等,不相等返回 true。

    [ $a != $b ] 返回 true。

    -z 检測字符串长度是否为0。为0返回 true。 [ -z $a ] 返回 false。
    -n 检測字符串长度是否为0,不为0返回 true。 [ -z $a ] 返回 true。

    str 检測字符串是否为空,不为空返回 true。 [ $a ] 返回 true。


    12.文件測试运算符

    文件測试运算符列表
    操作符 说明 举例
    -b file 检測文件是否是块设备文件。假设是,则返回 true。 [ -b $file ] 返回 false。

    -c file 检測文件是否是字符设备文件。假设是,则返回 true。 [ -b $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。


    13.凝视

    以“#”开头的行就是凝视,会被解释器忽略。

    sh里没有多行凝视。仅仅能每一行加一个#号

    仅仅能像这样:

    1. #--------------------------------------------
    2. # 这是一个自己主动打ipa的脚本,基于webfrogs的ipa-build书写:
    3. # https://github.com/webfrogs/xcode_shell/blob/master/ipa-build
    4.  
    5. # 功能:自己主动为etao ios app打包。产出物为14个渠道的ipa包
    6. # 特色:全自己主动打包,不须要输入不论什么參数
    7. #--------------------------------------------
    假设在开发过程中,遇到大段的代码须要暂时凝视起来。过一会儿又取消凝视,怎么办呢?每一行加个#符号太费力了,能够把这一段要凝视的代码用一对花括号括起来,定义成一个函数,没有地方调用这个函数,这块代码就不会运行,达到了和凝视一样的效果。

    14.获取字符串长度

    1. string="abcd"
    2. echo ${#string} #输出 4

    提取字符串

    1. string="alibaba is a great company"
    2. echo ${string:1:4} #输出liba

    查找字符串

    1. string="alibaba is a great company"
    2. echo `expr index "$string" is`#输出3(i是第3个字符)

    15.定义数组

    在Shell中。用括号来表示数组,数组元素用“空格”符号切割开

    定义数组的一般形式为:
        array_name=(value1 ... valuen)
    比如:

    1. array_name=(value0 value1 value2 value3)

    还能够单独定义数组的各个分量:

    1. array_name[0]=value0
    2. array_name[1]=value1
    3. array_name[2]=value2
    能够不使用连续的下标。并且下标的范围没有限制。 

    读取数组元素值的一般格式是:

        ${array_name[index]}
    比如:

    1. valuen=${array_name[2]}
    使用@ 或 * 能够获取数组中的全部元素,比如:
    
    
    1. ${array_name[*]}
    2. ${array_name[@]}
    举个样例:
    1. #!/bin/sh
    2.  
    3. NAME[0]="Zara"
    4. NAME[1]="Qadir"
    5. NAME[2]="Mahnaz"
    6. NAME[3]="Ayan"
    7. NAME[4]="Daisy"
    8. echo "First Method: ${NAME[*]}"
    9. echo "Second Method: ${NAME[@]}"
    执行脚本。输出:
    $./test.sh
    First Method: Zara Qadir Mahnaz Ayan Daisy
    Second Method: Zara Qadir Mahnaz Ayan Daisy
    
    
    获取数组长度的方法与获取字符串长度的方法同样,比如: 
    # 取得数组元素的个数
    1. length=${#array_name[@]}
    2. # 或者
    3. length=${#array_name[*]}
    4. # 取得数组单个元素的长度
    5. lengthn=${#array_name[n]}

    16.printf 命令用于格式化输出

    如同 echo 命令,printf 命令也能够输出简单的字符串:
    1. $printf "Hello, Shell "
    2. Hello, Shell
    3. $
    printf 不像 echo 那样会自己主动换行,必须显式加入换行符( )。



    printf 命令的语法:

    printf  format-string  [arguments...]
    format-string 为格式控制字符串,arguments 为參数列表。
    与C语言printf()函数的不同:
    • printf 命令不用加括号
    • format-string 能够没有引號,但最好加上,单引號双引號均可。
    • 參数多于格式控制符(%)时,format-string 能够重用。能够将全部參数都转换。
    • arguments 使用空格分隔,不用逗号。

    请看以下的样例:
    1. # format-string为双引號
    2. $ printf "%d %s " 1 "abc"
    3. 1 abc
    4. # 单引號与双引號效果一样
    5. $ printf '%d %s ' 1 "abc"
    6. 1 abc
    7. # 没有引號也能够输出
    8. $ printf %s abcdef
    9. abcdef
    10. # 格式仅仅指定了一个參数。但多出的參数仍然会依照该格式输出,format-string 被重用
    11. $ printf %s abc def
    12. abcdef
    13. $ printf "%s " abc def
    14. abc
    15. def
    16. $ printf "%s %s %s " a b c d e f g h i j
    17. a b c
    18. d e f
    19. g h i
    20. j
    21. # 假设没有 arguments,那么 %s 用NULL取代。%d 用 0 取代
    22. $ printf "%s and %d "
    23. and 0
    24. # 假设以 %d 的格式来显示字符串,那么会有警告,提示无效的数字,此时默认置为 0
    25. $ printf "The first program always prints'%s,%d '" Hello Shell
    26. -bash: printf: Shell: invalid number
    27. The first program always prints 'Hello,0'
    28. $
    注意。依据POSIX标准,浮点格式%e、%E、%f、%g与%G是“不须要被支持”。这是由于awk支持浮点预算,且有它自己的printf语句。

    这样Shell程序中须要将浮点数值进行格式化的打印时,可使用小型的awk程序实现。然而,内建于bash、ksh93和zsh中的printf命令都支持浮点格式。


    17.for循环

    for循环一般格式为:
    for 变量 in 列表
    do
        command1
        command2
        ...
        commandN
    done
    列表是一组值(数字、字符串等)组成的序列,每一个值通过空格分隔。每循环一次。就将列表中的下一个值赋给变量。



    in 列表是可选的,假设不用它。for 循环使用命令行的位置參数。



    比如,顺序输出当前列表中的数字:

    1. for loop in 1 2 3 4 5
    2. do
    3. echo "The value is: $loop"
    4. done
    执行结果:
    The value is: 1
    The value is: 2
    The value is: 3
    The value is: 4
    The value is: 5

    顺序输出字符串中的字符:
    1. for str in 'This is a string'
    2. do
    3. echo $str
    4. done
    执行结果:
    This is a string
    假设不加引號则输出:
    This
    is
    a
    string
    显示主文件夹下以 .bash 开头的文件:
    1. #!/bin/bash
    2.  
    3. for FILE in $HOME/.bash*
    4. do
    5. echo $FILE
    6. done
    执行结果:
    /root/.bash_history
    /root/.bash_logout
    /root/.bashrc

    18.函数

    函数能够让我们将一个复杂功能划分成若干模块。让程序结构更加清晰,代码反复利用率更高。

    像其它编程语言一样。Shell 也支持函数。

    Shell 函数必须先定义后使用。

    Shell 函数的定义格式例如以下:

    function_name () {
        list of commands
        [ return value ]
    }
    假设你愿意,也能够在函数名前加上keyword function:
    function function_name () {
        list of commands
        [ return value ]
    }
    函数返回值。能够显式添加return语句;假设不加。会将最后一条命令执行结果作为返回值。

    Shell 函数返回值仅仅能是整数,一般用来表示函数运行成功与否。0表示成功,其它值表示失败。

    假设 return 其它数据,比方一个字符串。往往会得到错误提示:“numeric argument required”。



    假设一定要让函数返回字符串,那么能够先定义一个变量,用来接收函数的计算结果。脚本在须要的时候訪问这个变量来获得函数返回值。
    调用函数仅仅须要给出函数名。不须要加括号。


    看一个带有return语句的函数:
    1. #!/bin/bash
    2. funWithReturn(){
    3. echo "The function is to get the sum of two numbers..."
    4. echo -n "Input first number: "
    5. read aNum
    6. echo -n "Input another number: "
    7. read anotherNum
    8. echo "The two numbers are $aNum and $anotherNum !"
    9. return $(($aNum+$anotherNum))
    10. }
    11. funWithReturn
    12. # Capture value returnd by last command
    13. ret=$?
    14. echo "The sum of two numbers is $ret !"
    执行结果:
    The function is to get the sum of two numbers...
    Input first number: 25
    Input another number: 50
    The two numbers are 25 and 50 !
    The sum of two numbers is 75 !
    函数返回值在调用该函数后通过 $? 来获得
    假设你希望直接从终端调用函数。能够将函数定义在主文件夹下的 .profile 文件。这样每次登录后,在命令提示符后面输入函数名字就能够马上调用

    19.函数调用

    在Shell中,调用函数时能够向其传递參数。在函数体内部,通过 $n 的形式来获取參数的值,比如。$1表示第一个參数,$2表示第二个參数...

    带參数的函数演示样例:
    1. #!/bin/bash
    2. funWithParam(){
    3. echo "The value of the first parameter is $1 !"
    4. echo "The value of the second parameter is $2 !"
    5. echo "The value of the tenth parameter is $10 !" # $1的值 和 0
    6. echo "The value of the tenth parameter is ${10} !"
    7. echo "The value of the eleventh parameter is ${11} !"
    8. echo "The amount of the parameters is $# !" # 參数个数
    9. echo "The string of the parameters is $* !" # 传递给函数的全部參数
    10. }
    11. funWithParam 1 2 3 4 5 6 7 8 9 34 73
    #!/bin/bash
    funWithParam(){
        echo "The value of the first parameter is $1 !"
        echo "The value of the second parameter is $2 !"
        echo "The value of the tenth parameter is $10 !"
        echo "The value of the tenth parameter is ${10} !"
        echo "The value of the eleventh parameter is ${11} !"
        echo "The amount of the parameters is $# !"  # 參数个数
        echo "The string of the parameters is $* !"  # 传递给函数的全部參数
    }
    funWithParam 1 2 3 4 5 6 7 8 9 34 73
    执行脚本:
    The value of the first parameter is 1 !
    The value of the second parameter is 2 !
    The value of the tenth parameter is 10 ! 
    The value of the tenth parameter is 34 !
    The value of the eleventh parameter is 73 !
    The amount of the parameters is 11 !
    The string of the parameters is 1 2 3 4 5 6 7 8 9 34 73 !"
    注意,$10 不能获取第十个參数,获取第十个參数须要${10}。当n>=10时,须要使用${n}来获取參数。


  • 相关阅读:
    MySQL group_concat() 函数用法
    Git error The file will have its original line endings in your working directory
    SQL exists 基本用法
    (11) 严格模式(use strict)
    (10)变量提升
    (9)调试
    (8)正则表达式
    (7)类型转换
    (6)typeof, null, 和 undefined
    (5)运算符
  • 原文地址:https://www.cnblogs.com/llguanli/p/6915713.html
Copyright © 2020-2023  润新知