美文网首页
第11章:构建基本脚本

第11章:构建基本脚本

作者: MrDecoder | 来源:发表于2019-09-20 14:21 被阅读0次

    [TOC]


    1. 使用多个命令

    shell脚本的关键在于输入多个命令并处理每个命令的结果,甚至需要将一个命令的结果传给另一个命令。shell可以将多个命令串起来,一次执行完成。如果要两个命令一起运行,可以把它们放在同一行中,彼此用分号隔开。

    $ date;who
    2019年 09月 19日 星期四 19:59:03 CST
    henryhu  tty7         2019-09-19 10:49 (:0)
    

    这个简单的脚本只用到了两个bash shell命令。date命令先运行,显示了当前日期和时间,后面紧跟着who命令的输出,显示当前是谁登陆到了系统上。

    2. 创建shell脚本文件

    要将shell命令放到文本文件中,首先需要用文本编辑器来创建一个文件,然后将命令输入到文件中。

    在创建shell脚本文件时,必须在文件的第一行指定要使用的shell。其格式为:

    #!/bin/bash
    

    在通常的shell脚本中,# 用作注释行。shell并不会处理shell脚本中的注释行。然而,shell脚本文件的第一行是个例外,# 后面的 ! 会告诉shell用哪个shell来运行脚本(你可以使用bash shell,同时还可以使用另一个shell来运行你的脚本)。

    在指定了shell之后,就可以在文件的每一行中输入命令,然后加一个回车符。

    #!/bin/bash
    # This script displays the date and who's logged on
    date
    who
    

    可以根据需要,使用分号(;)将两个命令放在一行上,但在shell脚本中,你可以在独立的行中书写命令。shell会根据命令在文件中出现的顺序进行处理。

    将这个脚本保存在名为test1的文件中,基本就好了。在运行新脚本前,还要做其他一些事。现在运行脚本会出现以下情况:

    $ test1
    No command 'test1' found, did you mean:
     Command 'test' from package 'coreutils' (main)
     Command 'testr' from package 'python-testrepository' (universe)
     Command 'testr' from package 'python3-testrepository' (main)
    test1: command not found
    

    需要解决的第一个问题就是让bash shell能找到你的脚本文件。要让shell找到test1脚本,只需要采取以下两种方式之一:

    • 将shell脚本文件所在的目录添加到PATH环境变量;
    • 在提示符中用绝对或相对文件路径来引用shell脚本文件。

    在这个例子中,我们将用第二种方式将脚本文件的确切位置告诉shell。记住,为了引用当前目录下的文件,可以在shell中使用单点操作符。

    $ ./test1
    bash: ./test1.sh: Permission denied
    

    现在shell找到了脚本文件,但还有一个问题。shell指明了你还没有执行文件的权限。快速查找看一下文件权限就能找到问题所在。

    $ ls -l test1.sh
    -rw-r--r-- 1 root root 73 9月  19 20:16 test1.sh
    

    在创建test1文件时,umask的值决定了新文件的默认权限设置。由于unmask变量在Ubuntu中被设成了022,所以系统创建的文件只有文件属主和属组才有读/写权限。

    下一步是通过chmod命令赋予文件属主执行文件的权限。

    $ sudo chmod a+x test1.sh
    henryhu@henryhu-virtual-machine:~/bash-study$ ./test1.sh
    2019年 09月 19日 星期四 20:28:49 CST
    henryhu  tty7         2019-09-19 10:49 (:0)
    

    3. 显示消息

    大多数shell命令都会产生自己的输出,这些输出会显示在脚本所运行的控制台显示器上。通过echo命令用户可以添加自己的消息来告诉脚本用户脚本正在做什么。

    $ echo This is a test
    This is a test
    

    echo命令可用单引号或双引号来划定文本字符串。如果在字符串中用到它们,你需要在文本中使用其中一种引号,而另外一种来将字符串划定起来。

    $ echo "This is a test to see if you're paying attention"
    This is a test to see if you're paying attention
    $ echo 'Rich says "scripting is easy".'
    Rich says "scripting is easy".
    

    如果想把文本字符串和命令输出显示在同一行,可以用echo语句的-n参数。

    $ echo -n "The time and date are: "
    The time and date are: 2019年 09月 19日 星期四 20:38:29 CST
    

    4. 使用变量

    通常如果需要在shell命令中使用其他数据来处理信息。这可以通过变量来实现。变量允许临时性地将信息存储在shell脚本中,以便和脚本中的其他命令一起使用。

    4.1 环境变量

    shell维护这一组环境变量,用来记录特定的系统信息。比如系统的名称、登录到系统上的用户名、用户的系统ID(也称为UID)、用户的默认主目录以及shell查找程序的搜索路径可以用set命令来显示一份完整的当前环境变量列表。

    #!/bin/bash
    # display user information from the system.
    echo "User info for userid: $USER"
    echo UID:: $UID
    echo HOME: $HOME
    

    USER、UID、和$HOME环境变量用来显示已登录用户的有关消息。脚本输入如下:

    henryhu@henryhu-virtual-machine:~/bash-study$ ./test2.sh 
    User info for userid: henryhu
    UID:: 1000
    HOME: /home/henryhu
    

    4.2 用户变量

    除了环境变量,shell脚本还允许在脚本中定义和使用自己的变量。定义变量允许临时存储数据并在整个脚本中使用,从而使shell脚本看起来更像一个真正的计算机程序。

    用户变量可以是任何由字母、数字或下划线组成的文本字符串,长度不超过20个。用户变量区分大小写,所以变量var1和变量Var1是不同的。

    使用等号将值赋给用户变量。在变量、等号和值之间不能出现空格。

    var1=10
    var2=-57
    var3=testing
    var4="still more testing"
    

    shell脚本会自动决定变量值的数据类型。在脚本的整个生命周期里,shell脚本中定义的变量会一直保持者它们的值,但在shell脚本结束时会被删除。

    与系统变量类似,用户变量可通过美元符引用。

    #!/bin/bash
    # testing variables
    days=10
    guest="Katie"
    echo  "$guest checked in $days days ago"
    days=5
    guest="Jessica"
    echo "$guest checked in $days days ago"
    

    运行脚本会输出:

    Katie checked in 10 days ago
    Jessica checked in 5 days ago
    

    变量每次被引用时,都会输出当前赋给它的值。引用一个变量值时需要使用美元符($)。 没有美元符,shell会将变量解释成普通的文本字符串。

    4.3 命令替换

    shell脚本中最有用的特性之一就是可以从命令输出中提取信息,并将其赋给变量。

    有两种方法可以将命令输出赋给变量:

    • 反引号字符(`)
    • $()格式

    命令替换允许你将shell命令的输出赋给变量。要么用一对反引号把整个命令行命令围起来:

    testing=`date`
    

    要么使用$()格式:

    testing=$(date)
    

    shell会运行命令替换符号中的命令,并将其输出赋给变量testing。注意,赋值等号和命令替换字符之间没有空格。

    #!/bin/bash
    testing=$(date)
    echo "The date and time are: " $testing
    

    变量testing获得了date命令的输出,然后使用echo语句显示它的值。运行这个shell脚本输出如下:

    The date and time are:  2019年 09月 20日 星期五 10:44:13 CST
    

    5. 重定向输入和输出

    bash shell提供了几个操作符,可以将命令的输出重定向到另一个位置(比如文件)。重定向可以用于输入,也可以输出,可以将文件重定向到命令输入。

    5.1 输出重定向

    最基本的重定向将命令的输出发送到一个文件中。bash shell用(>)来完成这项功能:

    command > outputfile
    

    之前显示器上出现的命令输出会被保存到指定的输出文件中。

    $ cat test5
    $ ls -l test5
    -rw-rw-rw- 1 root root 0 9月  20 11:00 test5
    $ cat test5
    2019年 09月 20日 星期五 11:02:03 CST
    

    重定向操作符创建了一个文件test5(通过默认的umask设置),并将date命令的输出重定向到该文件中。如果输出文件以及存在了,重定向操作符会用新的文件数据覆盖已有文件。

    如果不需要覆盖输出,可以用双大于号(>>)来追加数据。

    5.2 输入重定向

    输入重定向和输出重定向正好相反。输入重定向将文件的内容重定向到命令,而非将命令的输出重定向到文件。

    输入重定向符号是小于号(<):

    还有另外一种输入重定向的方法,称为内联输入重定向。这种方法无需使用文件进行重定向,只需要在命令行中指定用于重定向的数据就可以了。

    内联输入重定向符号是远小于号(<<)。除了这个符号,你必须指定一个文本标记来划分输入数据的开始和结尾。任何字符串都可作为文本标记,但在数据的开始和结尾文本标记必须一致。

    command << marker
    data
    marker
    

    在命令行上使用内联输入重定向时,shell会用PS2环境变量中定义的次提示符来提示输入数据。

    $ wc << EOF
    > test string 1
    > test string 2
    > test string 3
    > EOF
     3  9 42
    

    6. 管道

    有时需要将一个命令的输出作为另一个命令的输入。这可以用重定向来实现。最直接的一种方式是通过管道连接。

    command1 | command2
    

    7. 执行数学运算

    在shell脚本中有两种途径来进行数学运算。

    7.1 expr命令

    最开始,Bourne shell提供了一个特别的命令用来处理数学表达式。expr命令允许在命令行上处理数学表达式,但是特别笨拙。

    $ expr 1 + 5
    6
    

    expr命令能够识别少数的数学和字符串操作符,尽管标准操作符在expr命令中工作得很好,但在脚本或命令行上使用它们仍有问题出现。

    $ expr 5 * 2
    expr: syntax error
    

    要解决这个问题,对于那些容易被shell错误解释的字符,在它们传入expr命令之前,需要使用shell的转义字符(反斜线)将其标出来。

    $ expr 5 \* 2
    10
    

    在shell脚本中使用expr命令也同样复杂

    #!/bin/bash
    # An example of using the expr command
    var1=10
    var2=20
    var3=$(expr $var2 / $var1)
    echo The result is $var3
    
    The result is 2
    

    7.2 使用方括号

    bash shell为了保持跟Bourne shell的兼容而包含了expr命令,但它同样也提供了一种更简单的方法来执行数学表达式。在bash中,在将一个数学运算结果赋给某个变量时,可以用美元符和方括号($[operation])将数学表达式围起来。

    #!/bin/bash
    var1=$[1+5]
    echo $var1
    
    var2=$[$var1*2]
    echo $var2
    6
    12
    

    8. 退出脚本

    shell中运行的每个命令都使用退出状态码告诉shell它已经运行完毕。退出状态码是一个0-255的整数值,在命令结束运行时由命令传给shell。可以捕获这个值并在脚本中使用。

    8.1 查看退出状态码

    Linux提供了一个专门的变量?来保存已执行命令的退出状态码。对于需要进行检查的命令,必须在其运行完毕后立刻查看或使用?变量。它的值会变成由shell所执行的最后一条命令的退出状态码。

    $ date
    2019年 09月 20日 星期五 14:12:29 CST
    $ echo $?
    0
    

    8.2 exit命令

    默认情况下,shell脚本会以脚本中最后一个命令的退出状态码退出。你可以改变这种默认行为,返回自己的退出状态码。exit命令允许你在脚本结束时指定一个退出状态码。

    #!/bin/bash
    # testing the exit status
    var1=10
    var2=30
    var3=$[$var1 + $var2]
    echo The answer is $var3
    exit 5
    
    $ echo $?
    5
    

    相关文章

      网友评论

          本文标题:第11章:构建基本脚本

          本文链接:https://www.haomeiwen.com/subject/bwljuctx.html