`
java-mans
  • 浏览: 11388929 次
文章分类
社区版块
存档分类
最新评论

shell 程序设计3--- 那些年我们一起学习linux程序设计

 
阅读更多

8.命令列表

有时,我们想要将几条命令连接成一个序列。例如,我们可能想在执行某个语句之前满足好几个不同的条件,shell提供了一对特殊的结构,专门用于处理命令列表,他们分别是:AND列表和OR列表。虽然它们通常在一起使用,但我们将分别介绍它们的语法。

AND 列表

AND列表结构允许我们按照这样的方式执行一系列命令:只有在前面所有命令都执行成功的情况下才执行后一条命令。

它的语法是

statement1 && statement2 && statement3 && ....

从左开始顺序执行每条命令,如果一条命令返回是true,它右边的下一条命令才能够执行。如此循环直到有一条命令返回false,或者列表中的所有命令都执行完毕。&&的作用是检查前一条命令的返回值。

如果AND列表中的所有命令都执行成功,就算它执行成功,否则就算它失败。

实验:AND列表

#!/bin/sh

touch file_one
rm -f file_two

if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo "there"
then
    echo -e "in if"
else
    echo -e "in else"
fi

exit 0


实验解析:

touch 创建了文件file_one ,rm 删除了文件 file_two ,所以&&列表执行[ -f file_one ] 语句执行成功,所以执行下一条命令echo "hello" ,这个命令也执行成功,(因为echo命令总是返回true)。当执行第三个测试命令[ -f file_two ] ,因为该文件已被删除所以执行结果为flase, if语句将执行else 部分语句。

OR列表

OR列表结构允许我们持续执行一系列命令直到有一条命令成功为止,其后的命令将不再被执行。

它的语法是:

statement1|| statement2 || statement3|| ....

从左开始顺序执行每条命令。如果一条命令返回是false,它的右边的下一条命令才能够被执行。如此循环直到有一条命令返回true,或者列表中的所有命令都执行完毕

实验:OR列表

#!/bin/sh

rm -f file_one

if [ -f file_one ] || echo "hello" || echo "there"
then
    echo "in if"
else
    echo "in else"
fi

exit 0

实验解析:

||的第一条语句返回是flase,继续执行下一条语句,echo "hello" 语句返回的是true, 所以直接执行then 部分

结果打印信息:

hello

in if

来看下面例子,就是对AND 和 OR最好的解析

例s5:

#!/bin/sh

Folder=/home

[-r “$folder”]&& echo “can read $folder” (&&前的条件为真时才执行&&后的语句)

[-f “$folder”] || echo “this is not file”(||前的条件为假时才执行||后的语句)

结果打印信息:

can read /home
this is not file

总结:
| | :直到遇到真(返回true)才不执行
&&:直到遇到假(返回flase)才不执行

<四>命令

1.eval命令

eval命令允许你对参数进行求值。它是shell的内置命令,通常不会以单独命令的形式存在。我们可以借用X/Open规范中的一个小例子来演示它的用法。

foo=10

x=foo

y=‘$' $x

echo $y

它输出“$foo”而

foo=10

x=foo

eval y='$'$x

echo $y

输出 10.因此,eval命令有点像一个额外的$,它给出一个变量的值的值。

2.exit n 命令

在shell脚本编程中,退出码0表示成功,退出码1~125是脚本程序使用的错误代码。其余数字具有保留含义。

退出码 说明

126

127

128以上

文件不可执行

命令未找到

出现信号

3. export 命令

export命令将作为它参数的变量导出到子shell中,并使之在子shell中有效。默认情况下,在一个shell中被创建的变量在这个shell调用的下级(子)shell中是不可用的。export命令把自己的参数创建为一个环境变量,而这个环境变量可以被其他脚本和当前程序调用的程序看见。从更技术的角度说,被导出的变量构成从该shell衍生的任何子进程的环境变量。我们用下面两个脚本程序export1 和export2来说明。

实验:导出变量

(1)我们先列出脚本程序export2:
#!/bin/sh

echo "$foo"
echo "$bar"

(2)下面是脚本程序export1.在这个脚本的结尾,我们调用export2:
#!/bin/sh

foo="The first meta-syntactic variable"
export bar="The second meta-syntactic variable"

./export2


运行export1这个脚本程序,将得到如下输出:

The second meta-syntactic variable

第一个空行的出现是因为变量foo在export2中不可用,所以$foo被赋值为空,echo一个空变量将输出一个空行。

当变量被一个shell导出后,它就可以被该shell调用的任何脚本使用,也可被后续调用的任何shell使用。如果脚本export2调用了另一个脚本,bar的值对新脚本来说任然有效。

set -a 或 set -all export命令将导出它之后声明的所有变量

4.expr 命令

expr命令将它的参数当做一个表达式来求值。它的最常见的用法是进行如下的简答数学运算:

方法一: x=`expr $x+1`

反引号(` `)字符使x取值为命令expr$x+1的执行结果。我们也可以用语法$()替换反引号``,如下所示:

方法二:x=$(expr $x+1)

在最新的脚本程序中,expr命令被替换为更有效的$((...))语法,这个我们在后面提到。

5. set 命令

set 命令的作用是为shell设置参数变量。许多命令的输出结果是以空格分隔的值(域),如果需要使用输出结果中的某个域,这个命令就非常有用。

我们来看下面这个例子就容易明白了:

#!/bin/sh

echo The date is $(date)
set $(date)
echo The month is $2

exit 0

输出结果:

实验解析:

系统本身提供了一个data命令,它的输出时字符串形式的 年 月 日 星期 ... ,但是我们需要的是 月份这就需要将它与其他区域分隔开,我们使用set命令和$(...)结构的组合来date 的输出结果设置为参数列表,然后通过位置参数$2获得月份。 月份字符串是 date 命令输出结果的 第二个参数。

6.find命令

find命令的完整语法格式如下:

fine [path] [options] [test ] [actions]

实验:使用测试的find命令

当前目录下搜索比文件while2要新的文件

命令: find . -newer while2 -print

.

./elif3

./words.txt

./words2.txt

./_trap

这个结果看起来不错,不过结果中还包含了当前目录,而这个并不是我们想要的,我们只对普通文件感兴趣。所以我们需要增加一个额外的测试 -type f

./elif3

./words.txt

./words2.txt

./_trap

7.grep命令

grep命令时在文件中搜索字符串 find命令时在系统中搜索文件

<五>命令执行

编写脚本程序时,我们经常需要捕获一条命令的执行结果并把它用在shell脚本程序中,也就是说,我们想要执行一条命令并把该命令的输出到一个变量中。我们可以用前面set命令示例中介绍的$(command) 语法来实现,也可以用一种比较老的语法形式`command`,这种用法目前依然常见。

注意:在脚本程序里执行比较老的语法形式所使用的的反引号 ` ,而不是我们前面使用的单引号 ' (单引号是防止变量扩展)

所有的新脚本的程序都应该使用$(...)形式,引入这一形式的目的是避免在使用反引号时过于复杂。

$(command)的结果就是其中命令的输出。注意这不是该命令的退出状态,而是他的字符串形式的输出结果。例如:

#! /bin/sh

echo the current directory is $pwd

echo the currentuser is $(who)

exit 0

1.算术扩展

我们已经介绍过expr命令,它允许对简单的算术命令进行处理,但这个命令执行起来相当慢,因为它需要调用一条新的shell来处理expr命令,一种更好的办法就是使用$((...))扩展,如下:

#!  /bin/sh



x=0

while [ "$x"  -ne 10 ] ;do

       echo  $x

       x=$(($x+1))

done

exit  0

注意:这与x=$(...)命令不同,两对圆括号用于算术替换,而我们之前见到的一对圆括号用于命令的执行和获取输出

2.参数扩展

注意有时候变量名很容易与其他文字混淆,比如:

S13:

Num=2

Echo “this is the $numnd”

思考:输出?why?

答案:num=2

Echo “this is the $numnd”

这并不会打印出““this is the2nd”,而仅仅打印“this is the”,因为shell会去搜索变量numnd的值,但是这个变量是没有的。可以使用花括号来告诉shell我们要打印的是num变量:

Num=2

Echo “this is the ${num}nd”

这将打印:this is the 2nd

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics