zoukankan      html  css  js  c++  java
  • Shell脚本之四 内建命令

    所谓 Shell 内建命令,就是由 Bash 自身提供的命令,而不是文件系统中的某个可执行文件。

    可以使用 type 来确定一个命令是否是内建命令:

    [root@localhost ~]# type cd
    cd is a Shell builtin
    [root@localhost ~]# type ifconfig
    ifconfig is /sbin/ifconfig
    

    由此可见,cd 是一个 Shell 内建命令,而 ifconfig 是一个外部文件,它的位置是/sbin/ifconfig

    还记得系统变量 $PATH 吗?$PATH 变量包含的目录中几乎聚集了系统中绝大多数的可执行命令,它们都是外部命令。

    通常来说,内建命令会比外部命令执行得更快,执行外部命令时不但会触发磁盘 I/O,还需要 fork 出一个单独的进程来执行,执行完成后再退出。而执行内建命令相当于调用当前 Shell 进程的一个函数。

    接下来的几节我们将重点讲解几个常用的 Shell 内置命令。


    一、Shell alias命令

    使用 alias 命令自定义别名的语法格式为:

    alias new_name='command'
    

    比如,一般的关机命令是shutdown-h now,写起来比较长,这时可以重新定义一个关机命令,以后就方便多了。

    alias myShutdown='shutdown -h now'
    

    注意,别名只是临时的,在代码中使用 alias 命令定义的别名只能在当前 Shell 进程中使用,在子进程和其它进程中都不能使用。当前 Shell 进程结束后,别名也随之消失。要想让别名对所有的 Shell 进程都有效,就得把别名写入 Shell 配置文件。


    二、Shell echo命令

    Shell 的 echo 指令是用于字符串的输出。命令格式:

    echo string
    

    您可以使用echo实现更复杂的输出格式控制。注意,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 接收标准输入的变量,结果将是:

    $ ./test.sh
    OK                     #标准输入
    OK It is a test        #输出
    
    

    4.显示换行

    echo -e "OK! 
    " # -e 开启转义
    echo "It is a test"
    
    

    输出结果:

    OK!
    
    It is 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 #myfile若不存在,则也会创建myfile文件
    
    

    7.原样输出字符串,不进行转义或取变量(用单引号)

    echo '$name"'
    
    

    输出结果:

    $name"
    
    

    8.显示命令执行结果

    echo `date`
    
    

    注意: 这里使用的是反引号 `, 而不是单引号 '

    结果将显示当前日期

    Thu Jul 24 10:08:46 CST 2014
    
    

    echo输出的字符串总结如下表所示:

    引号类型 能否引用变量 能否引用符 能否引用文本格式符
    单引号
    双引号
    无引号

    三、Shell printf 命令

    本章节我们来学习 Shell 的另一个输出命令 printf。printf 命令模仿 C 语言的 printf() 程序。printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。

    printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 。

    printf 命令的语法:

    printf  format-string  [arguments...]
    
    

    参数说明:

    • format-string: 为格式控制字符串
    • arguments: 为参数列表。

    实例1

    $ echo "Hello, Shell"
    Hello, Shell
    $ printf "Hello, Shell
    "
    Hello, Shell
    
    

    接下来,我来用一个脚本来体现printf的强大功能:

    #!/bin/bash
     
    printf "%-10s %-8s %-4s
    " 姓名 性别 体重kg  
    printf "%-10s %-8s %-4.2f
    " 郭靖 男 66.1234 
    printf "%-10s %-8s %-4.2f
    " 杨过 男 48.6543 
    printf "%-10s %-8s %-4.2f
    " 郭芙 女 47.9876 
    
    

    执行脚本,输出结果如下所示:

    姓名     性别   体重kg
    郭靖     男      66.12
    杨过     男      48.65
    郭芙     女      47.99
    
    

    %-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。%-4.2f 指格式化为小数,其中.2指保留2位小数。


    实例2

    #!/bin/bash
    # author:菜鸟教程
    # url:www.runoob.com
     
    # format-string为双引号
    printf "%d %s
    " 1 "abc"
    
    # 单引号与双引号效果一样 
    printf '%d %s
    ' 1 "abc" 
    
    # 没有引号也可以输出
    printf %s abcdef
    
    # 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
    printf %s abc def
    
    printf "%s
    " abc def
    
    printf "%s %s %s
    " a b c d e f g h i j
    
    # 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
    printf "%s and %d 
    " 
    
    

    执行脚本,输出结果如下所示:

    1 abc
    1 abc
    abcdefabcdefabc
    def
    a b c
    d e f
    g h i
    j  
     and 0
    
    

    四、Shell read命令

    Shell中的 read 命令用来从标准输入中读取数据并赋值给变量。如果没有进行重定向,默认就是从键盘读取用户输入的数据;如果进行了重定向,那么可以从文件中读取数据。

    read 命令的用法为:

    read [-options] [variables]
    
    

    options表示选项,如下表所示;variables表示用来存储数据的变量,可以有一个,也可以有多个。options和variables都是可选的,如果没有提供变量名,那么读取的数据将存放到环境变量 REPLY 中。

    选项 说明
    -a array 把读取的数据赋值给数组 array,从下标 0 开始。
    -d delimiter 用字符串 delimiter 指定读取结束的位置,而不是一个换行符(读取到的数据不包括 delimiter)。
    -e 在获取用户输入的时候,对功能键进行编码转换,不会直接显式功能键对应的字符。
    -n num 读取 num 个字符,而不是整行字符。
    -p prompt 显示提示信息,提示内容为 prompt。
    -r 原样读取(Raw mode),不把反斜杠字符解释为转义字符。
    -s 静默模式(Silent mode),不会在屏幕上显示输入的字符。当输入密码和其它确认信息的时候,这是很有必要的。
    -t seconds 设置超时时间,单位为秒。如果用户没有在指定时间内输入完成,那么 read 将会返回一个非 0 的退出状态,表示读取失败。
    -u fd 使用文件描述符 fd 作为输入源,而不是标准输入,类似于重定向。

    实例1

    使用 read 命令给多个变量赋值:

    #!/bin/bash
    read -p "Enter some information > " name url age
    echo "网站名字:$name"
    echo "网址:$url"
    echo "年龄:$age"
    
    

    运行结果:

    Enter some information > 博客园 http://cnblogs.com 7
    网站名字:博客园
    网址:http://cnblogs.com
    年龄:7
    
    

    本例使用了-p选项,该选项会用一段文本来提示用户输入。注意,必须在一行内输入所有的值,不能换行,否则只能给第一个变量赋值,后续变量都会赋值失败。


    实例2

    在指定时间内输入密码:

    #!/bin/bash
    if
        read -t 20 -sp "Enter password in 20 seconds(once) > " pass1 && printf "
    " &&  #第一次输入密码
        read -t 20 -sp "Enter password in 20 seconds(again)> " pass2 && printf "
    " &&  #第二次输入密码
        [ $pass1 == $pass2 ]  #判断两次输入的密码是否相等
    then
        echo "Valid password"
    else
        echo "Invalid password"
    fi
    
    

    运行结果:

    #如果两次输入密码相同,运行结果为:
    Enter password in 20 seconds(once) >
    Enter password in 20 seconds(again)>
    Valid password
    
    #如果两次输入密码不同,运行结果为:
    Enter password in 20 seconds(once) >
    Enter password in 20 seconds(again)>
    Invalid password
    
    #如果第一次输入超时,运行结果为:
    Enter password in 20 seconds(once) > Invalid password
    
    #如果第二次输入超时,运行结果为:
    Enter password in 20 seconds(once) >
    Enter password in 20 seconds(again)> Invalid password
    
    

    这段代码中,我们使用&&组合了多个命令,这些命令会依次执行,并且从整体上作为 if 语句的判断条件,只要其中一个命令执行失败(退出状态为非 0 值),整个判断条件就失败了,后续的命令也就没有必要执行了。


    五、Shell test 命令

    Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试,一般搭配 if 命令使用。


    1.数值测试

    实例演示:

    num1=100
    num2=100
    if test $num1 -eq $num2
    then
        echo '两个数相等!'
    else
        echo '两个数不相等!'
    fi
    
    

    输出结果:

    两个数相等!
    
    

    2.字符串测试

    实例演示:

    num1="ru1noob"
    num2="runoob"
    if test $num1 = $num2
    then
        echo '两个字符串相等!'
    else
        echo '两个字符串不相等!'
    fi
    
    

    输出结果:

    两个字符串不相等!
    
    

    3.文件测试

    实例演示:

    cd /bin
    if test -e ./bash
    then
        echo '文件已存在!'
    else
        echo '文件不存在!'
    fi
    
    

    输出结果:

    文件已存在!
    
    

    另外,Shell还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为:"!"最高,"-a"次之,"-o"最低。例如:

    cd /bin
    if test -e ./notFile -o -e ./bash
    then
        echo '至少有一个文件存在!'
    else
        echo '两个文件都不存在'
    fi
    
    

    输出结果:

    至少有一个文件存在!
    
    

    六、Shell test 命令

    Shell中的 exit 命令用来退出当前 Shell 进程,并返回一个退出状态;使用 $? 可以接收这个退出状态。exit 退出状态只能是一个介于 0~255 之间的整数,其中只有 0 表示成功,其它值都表示失败。

    实例演示:

    #!/bin/bash
    
    echo "befor exit"
    exit 8
    echo "after exit"
    
    

    运行该脚本:

    $ ./test.sh
    befor exit
    
    $ echo $?
    8
    
    

    可以看到,"after exit" 并没有输出,这说明遇到 exit 命令后,test.sh 执行就结束了。另外,我们可以紧接着使用 $? 来获取 test.sh 的退出状态。


    七、Shell declare 命令

    Shell中的 declare 命令用来设置变量的属性。

    declare 命令的用法如下所示:

    declare [+/-] [aAfFgilprtux] [变量名=变量值]
    
    

    其中,- 表示设置属性,+ 表示取消属性,aAfFgilprtux 都是具体的选项,它们的含义如下表所示:

    选项 含义
    -f [name] 列出之前由用户在脚本中定义的函数名称和函数体。
    -F [name] 仅列出自定义函数名称。
    -g name 在 Shell 函数内部创建全局变量。
    -p [name] 显示指定变量的属性和值。
    -a name 声明变量为普通数组。
    -A name 声明变量为关联数组(支持索引下标为字符串)。
    -i name 将变量定义为整数型。
    -r name[=value] 将变量定义为只读(不可修改和删除),等价于 readonly name。
    -x name[=value] 将变量设置为环境变量,等价于 export name[=value]。

    实例1

    将变量声明为整数并进行计算:

    #!/bin/bash
    
    declare -i m n ret  #将多个变量声明为整数
    m=10
    n=30
    ret=$m+$n
    echo $ret
    
    

    运行该脚本:

    $ ./test.sh
    40
    
    

    实例2

    将变量定义为只读变量:

    #!/bin/bash
    
    declare -r n=10
    n=20
    
    

    运行该脚本:

    $ ./test.sh
    bash: n: 只读变量
    
    

    参考:

    Shell echo命令

    Shell printf 命令

    Shell test 命令

    Shell内建命令(内置命令)


  • 相关阅读:
    spark视频-Spark Streaming实时计算和流处理
    spark视频-Spark把云计算大数据速度提高100倍以上
    spark视频-Spark on Docker深入揭秘
    spark视频-Spark as a Service
    spark视频-Spark on Yarn
    MyEclipse Web 项目导入 Eclipse 中需要改的文件
    【解决】小米M1刷机教程(卡刷)
    【解决】笔记本发射WiFi
    【解决】U盘装系统(Win7/Win8)& 装双系统
    【解决】Internet访问看似正常(无叹号受限)却打不开网页
  • 原文地址:https://www.cnblogs.com/linuxAndMcu/p/11119478.html
Copyright © 2011-2022 走看看