Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6324596
  • 博文数量: 2759
  • 博客积分: 1021
  • 博客等级: 中士
  • 技术积分: 4091
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-11 14:14
文章分类

全部博文(2759)

文章存档

2019年(1)

2017年(84)

2016年(196)

2015年(204)

2014年(636)

2013年(1176)

2012年(463)

分类: LINUX

2013-10-04 10:02:54

原文地址:Shell之命令 作者:scq2099yt

        你可以在Shell脚本程序内部执行两类命令:内部命令和外部命令。内部命令是在Shell内部实现的,不能作为外部程序被调用,但相比外部命令而言内部命令执行更有效率,不过本文中并不区分内部还是外部命令。
一、break命令
        这个命令可以用于跳出for、while或者until循环。
        不过与C语言不同的是可以为break命令提供一个额外的数值参数来表明所要跳出的循环层数,但并不建议这么做,因为这会大大降低程序的可读性。
        默认情况下,break只跳出一层循环。

二、:命令
        冒号:命令是一个空命令。它偶尔会被用于简化条件逻辑,相当于true的一个别名。由于它是内置命令,所以它运行得比true快,但它的输出可读性比较差。
        你可能会看到将它用作while循环的条件,while :实现了一个无线循环,代替了更常见的while true。
        :结构也会被用在变量的条件设置中,例如:
        : ${var := value}
        如果没有:,shell将试图把$var当作一条命令来处理。
        
三、continue命令
        非常类似于C语言中的同名语句,这个命令使for、while或until循环跳到下一次循环继续执行,循环变量取循环列表中的下一个值。
        continue可以带一个可选的参数以表示希望继续执行的循环嵌套层数,也就是说你可以部分的跳出嵌套循环。这个参数很少用,因为它会致使脚本程序极难理解,比如:
        for x in 1 2 3
        do
            echo before $x
            continue 1
            echo after $x
        done
        上面程序输出:
        before 1
        before 2
        before 3

四、.命令
        点.命令用来执行当前shell中的命令:
        . ./shell_script
        通常,当一个脚本执行一条外部命令或脚本程序时,会创建一个新的环境(一个子shell),命令将在这个新环境中执行,在命令执行完毕后,这个环境被丢弃,只留下退出码返回给父shell。而外部的source命令和点命令(这两个命令差不多是同义词)在执行某个脚本程序中列出的命令时,使用的是调用该脚本程序的同一个shell。通常被调用命令对环境变量做出的任何改变都会丢失,而点命令允许执行的命令改变当前环境。当你要把一个脚本当做“包裹器”来为后续执行的一些命令设置环境时,这个命令通常就很有用。
        在shell脚本程序中,点命令的作用有点类似于C和C++语言里的#include指令,尽管它并没有从字面意义上包含脚本,但它的确是在当前上下文中执行命令,所以你可以使用它将变量和函数定义结合进一个脚本程序。

五、echo命令
        echo命令用来输出结尾带有换行符的字符串,当然也可以如下来去掉换行符:
        echo -n "string to output"

六、eval命令
        eval命令允许你对参数进行求值,举例说明如下:
        foo = 10
        x = foo
        y = '$'$x
        echo $y
        执行上面脚本输出"$foo"。
        foo = 10
        x = foo
        eval y='$'$x
        echo $y
        执行上面脚本输出10,因此,eval命令有点像一个额外的$,它给出一个变量的值的值。
        eval命令十分有用,它允许代码被随时生成和运行,虽然这会增加脚本调试的复杂度,但它可以让你完成使用其它方法难以或者根本无法完成的事情。
        
七、exec命令
        exec命令有两种不同的用法。它的典型用法是将当前shell替换为一个不同的程序,比如:
        exec wall "Thanks for all the fish"
        脚本中的这个命令会用wall命令替换当前的shell,脚本程序中exec命令后面的代码都不会执行,因为执行这个脚本的shell已经不存在了。
        exec的第二种用法是修改当前文件描述符:
        exec 3< afile
        这使得文件描述符3被打开以便从文件afile中读取数据,这种用法非常少见。
        
八、exit n命令
        exit命令使脚本程序以退出码n结束运行,如果你在任何一个交互式shell的命令提示符中使用这个命令,它都会让你退出系统。如果你允许自己的脚本程序在退出时不指定一个退出状态,那么该脚本中最后一条被执行命令的状态将被用作返回值。
        在shell脚本编程中,退出码0表示成功,退出码1~125是脚本程序使用的错误码,其余数字具有保留意义,比如:126表示文件不可执行、127表示命令未找到、128及以上表示出现一个信号。

九、export命令
        export命令将作为它参数的变量导出到子shell中,并使之在子shell中有效。默认情况下,在一个shell中被创建的变量在这个shell调用的下级(子)shell中是不可用的。export命令把自己的参数创建为一个环境变量,而这个环境变量可以被其它脚本和当前程序调用的程序看见,即被导出的变量构成从该shell衍生的任何子进程的环境变量。举例说明如下:
        (1)脚本程序export2:
        #!/bin/sh
        echo "$foo"
        echo "$bar"
        (2)脚本程序export1,这个脚本调用了export2:
        #!/bin/sh
        foo = "The first meta-syntactic varible"
        export bar = "The second meta-syntactic variable"
        export2
        运行脚本export1:
        $export1
        
        The second meta-syntactic variable
        第一个空行的出现是因为变量foo在export2中不可用,所以$foo被赋值为空,echo一个空变量将输出一个空行。
        当变量被一个shell导出后,它就可以被该shell调用的任何脚本使用,也可以被后续调用的任何shell使用。如果脚本export2调用了另一个脚本,bar的值对新脚本来说仍然有效。
        set -a或者set -allexport命令将导出它之后声明的所有变量。

十、expr命令
        expr命令将它的参数当作一个表达式求值,它的最常见用法就是进行如下形式的简单数学运算:
        x = `expr $x + 1`
        反引号字符使x取值为命令expr $x + 1的执行结果。我们也可以用语法$()替换反引号:
        x = $(expr $x + 1)
        expr命令功能很强大,可以完成许多表达式求值计算:
        expr1 | expr2:如果expr1非零,则等于expr1,否则等于expr2
        expr1 & expr2:只要有一个表达式为零,则等于零,否则等于expr1
        expr1 = expr2:等于
        expr1 > expr2:大于
        expr1 >= expr2:大于等于
        expr1 < expr2:小于
        expr1 <= expr2:小于等于
        expr1 != expr2:不等于
        expr1 + expr2:加法
        expr1 - expr2:减法
        expr1 * expr2:乘法
        expr1 / expr2:整除
        expr1 % expr2:取余

        在最新的脚本程序中,expr命令通常被替换为更有效的$((...))语法。


十一、printf命令
        printf命令用来代替echo命令以产生格式化的输出,其语法格式如下:
        printf "format string" parameter1 parameter2 ...
        格式字符串与C/C++相似,但不支持浮点数,因为shell中所有算术运算都是按照整数进行计算的。举例说明如下:
        $printf "%s\n" hello
        hello
        $printf "%s %d\t%s" "Hi There" 15 people
        Hi There 15    people
        注意:必须使用双引号括住Hi There字符串,使之成为一个单独的参数。

十二、return命令
        return命令的作用是使函数返回,其有一个数值参数,这个参数在调用函数的脚本程序里被看做该函数的返回值,如果没有指定参数,return命令默认返回最有一条命令的退出码。

十三、set命令
        set命令的作用是为shell设置参数变量。许多命令的输出结果是以空格分隔的值,如果需要使用输出结果中的某个域,这个命令就非常有用。
        比如:我们想在shell脚本中使用当前月份的名字,那么可以使用set命令和$(...)结构的组合来执行date命令以提取月份字符串。
        #!/bin/sh
        echo the date is $(date)
        set $(date)
        echo The month is $2
        exit 0
        这个程序把date命令的输出设置为参数列表,然后通过位置参数$2获取月份。

十四、shift命令
        shift命令把所有参数变量左移一个位置,使$2变成$1,$3变成$2,依此类推。原来$1的值将被丢弃,而$0仍将保持不变。如果调用shift命令时指定了一个数值参数,则表示所有的参数将左移指定的次数。$*、$@和$#等其它变量也将根据参数变量的新安排做相应的变动。在扫描处理脚本程序的参数时经常要用到shift命令,假如你的脚本程序需要10个或以上的参数,你就需要用shift命令访问第10个及其后面的参数,下面举例说明如何依次扫描所有的位置参数:
        #!/bin/sh
        while [ "$1" != "" ]; do
            echo "$1"
            shift
        done
        exit 0

十五、trap命令
        trap命令用于指定在接收到信号后将要采取的行动,trap命令的一种常见用途是在脚本程序被中断时完成清理工作。历史上,shell总是用数字来代表信号,而新的脚本程序应该使用信号的名字,它们保存在signal.h头文件中,在使用信号名时需要省略SIG前缀,你可以在命令提示符下输入命令trap -l来查看信号编号及其关联的名称。
        trap命令的参数分为两部分,前一部分是接收到指定信号时将要采取的行动,后一部分是要处理的信号名:
        trap command signal
        需要注意的是:脚本程序通常是以从上到下的顺序解释执行的,所以必须在你想保护的那部分代码以前指定trap命令。
        如果要重置某个信号的处理条件到其默认值,只需简单地将command设置为-。如果要忽略某个信号,就把command设置为空字符串‘’。一个不带参数的trap命令将列出当前设置的信号及其行动的清单。
        能够被捕获的比较重要的信号如下,括号中的数字表示信号编号,更多细节请man 7 signal查看: 
        HUP(1):挂起,通常因终端掉线或用户退出而引发。
        INT(2):中断,通常因按下Ctrl+C组合键而引发。
        QUIT(3) :退出,通常因按下Ctrl+\组合键而引发。
        ABRT(6):中止,通常因某些严重的执行错误而引发。
        ALRM(14):报警,通常用来处理超时。
        TERM(15):终止,通常在系统关机时发送。
        下面的脚本演示了一些简单地信号处理方法:
        #!/bin/sh
        trap 'rm -f /tmp/my_temp_file_$$' INT
        echo createing file /tmp/my_tmp_file_$$
        echo "press interrupt CTRL+C to interrupt ..."
        while [ -f /tmp/my_tmp_file_$$ ] ; do
            echo File exists
            sleep 1
        done
        echo The file no longer exists
        trap INT
        echo createing file /tmp/my_tmp_file_$$
        echo "press interrupt CTRL+C to interrupt ..."
        while [ -f /tmp/my_tmp_file_$$ ]; do
            echo File exists
            sleep 1
        done
        echo we never get here
        exits
        执行上面脚本,按下CTRL+C,将输出如下:
        create file /tmp/my_tmp_file141
        pree interrupt CTRL+C to interrupt ...
        File exists
        File exists
        The file no longer exists
        create file /tmp/my_tmp_file_141
        press interrupt CTRL+C to interrupt ...
        File exists
        File exists
        File exists
        在这个脚本程序中,先用trap命令安排它在出现一个INT信号时执行rm -f /tmp/my_tmp_file_$$命令删除临时文件。脚本程序然后进入一个while循环,只要临时文件存在,循环就一直持续下去。当用户按下CTRL+C时,就会删除临时文件,随之第一个while循环将正常退出。接下来,脚本程序再次调用trap命令用以指定当出现一个INT信号时不执行任何命令。脚本程序然后重新创建临时文件并进入第二个while循环。当用户再次按下CTRL+C时,没有语句被指定执行,所以才有默认处理方式,即立即终止脚本程序,故永远不会执行最后的echo和exit语句。     

十六、unset命令
        unset命令的作用是从环境变量中删除变量或函数。这个命令不能删除shell本身定义的只读变量(如IFS)。下面脚本第一次输出字符串“Hello World”,但第二次只输出一个换行符:
        #!/bin/sh
        foo = "Hello World"
        echo $foo
        unset $foo
        echo $foo
        使用foo=语句产生的效果与unset命令差不多但并不等同。foo=将变量foo设置为空,但变量foo仍然存在,而使用unset foo语句的效果是把变量foo从环境中删除。
        


阅读(785) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~