红联Linux门户
Linux帮助

常用的shell程序设计小知识

发布时间:2006-11-12 00:43:14来源:红联作者:Community
一、用户登陆进入系统后的系统环境变量:



$HOME 使用者自己的目录

$PATH 执行命令时所搜寻的目录

$TZ 时区

$MAILCHECK 每隔多少秒检查是否有新的信件

$PS1 在命令列时的提示号

$PS2 当命令尚未打完时,Shell 要求再输入时的提示号

$MANPATH man 指令的搜寻路径



二、特殊变量:



$0 这个程序的执行名字

$n 这个程序的第n个参数值,n=1..9

$* 这个程序的所有参数

$# 这个程序的参数个数

$$ 这个程序的PID

$! 执行上一个指令的PID

$? 执行上一个指令的返回值



三、shell中的变元:



* 任意字符串

? 一个任意字符

[abc] a, b, c三者中之一

[a-n] 从a到n的任一字符



四、几个特殊字符表示



\b 退回

\c 打印一行时没有换行符 这个我们经常会用到

\f 换页

\r 回车

\t 制表

\v 垂直制表

\\ 反斜线本身



五、判断文件的属性



格式:-操作符 filename

-e 文件存在返回1, 否则返回0

-r 文件可读返回1,否则返回0

-w 文件可写返回1,否则返回0

-x 文件可执行返回1,否则返回0

-o 文件属于用户本人返回1, 否则返回0

-z 文件长度为0返回1, 否则返回0.

-f 文件为普通文件返回1, 否则返回0

-d 文件为目录文件时返回1, 否则返回0



六、测试字符串



字符串1 = 字符串2 当两个字串相等时为真

字符串1 != 字符串2 当两个字串不等时为真

-n 字符串      当字符串的长度大于0时为真

-z 字符串      当字符串的长度为0时为真

字符串       当串字符串为非空时为真



七、测试两个整数关系



数字1 -eq 数字2     两数相等为真

数字1 -ne 数字2     两数不等为真

数字1 -gt 数字2     数字1大于数字2为真

数字1 -ge 数字2     数字1大于等于数字2为真

数字1 -lt 数字2     数字1小于数字2为真

数字1 -le 数字2     数字1小于等于数字2为真



八、逻辑测试



-a         与

-o        或

!        非



今天介绍shell特殊字符的引用

===============================

shell中的特殊字符有



1、$ 美元符

2、\ 反斜杠

3、` 反引号

4、" 双引号

5、< ,>,*,?,[,]



下面我一一举列说明



一、$符号



1、echo $? 显示的是上一条指令退出状态

2、echo "$?" 效果同上

3、echo '$?' 显示的是$?

4、echo \$? 显示的是$?

5、echo "\$?" 显示的是$?



  大家可能已经看出,$符号在双引号中具有特殊意义,双引号对$符号不起作用而单引号可以将特殊字符的的特殊意义屏蔽掉,使其能显示为字符本身,反斜杠也可以将特殊字符的特殊含义屏蔽掉,使特殊字符失去特殊含义。



二、\ 反斜杠



  反斜杠的作用是将特殊符号字符的特殊含义屏蔽掉,使其还是原字符

A=1234

echo \$A 显示为$A 如果不加\将显示为1234

echo \` 显示为`

echo \" 显示为双引号

echo \\ 显示为\



三、` 反引号



  反引号的功能是命令替换,将反引号中的字符串做为命令来执行,我们在用shell编程时经常用的到 将系统命令的执行结果赋给一个变量



A=`date`

echo $A 显示的不是date而是当时的时间串

比如有一文件A的内容如下 

ABCDEFG

1234456

abcdefg



B=`cat A|grep 234`? # 检索文件A中含有字符串234的行

echo $B 将显示为1234456

echo "$B" 将显示为什么?

echo "\$B" 将显示为什么?读者自己试试



四、" 双引号



  在系统中有些特殊字符,为避免引用这些特殊字符,往往用双引号或单引号将这些特殊字符引起来,使其不具有特殊含义。

  但有一部分特殊字符在引号中还是具有特殊含义,用双引号引起来是不起作用的。本文中所列的前四个特殊字符在双引号中还是特殊字符。为了使其不具有特殊含义一是用单引号引进来二是用\反斜线使其失去作用。



  比如我们想原样输出这些特殊字符



echo """

echo "$"

echo "\"

echo "`"

   以上不是你所期望的结果,因为双引号对它们不起作用,你只能这样才能输出这些特殊字符的原形

echo '"'

echo '$'

echo '\'

echo '`'



echo "\""

echo "\$"

echo "\\"

echo "\`"

将分别显示为 " $ \ `



五、其它特殊字符



  大家注意到,除了前四个特殊字符外,我将其它的特殊字符都放在一块,这是因为前四个特殊字符在双引号中还是具有特殊含义,所以单独拿出来讲,除此以外的特殊字符如果你要输出这些特殊字符的原形,你就可以用双引号或单引号引起来使其失去特殊含义。

< ,>,*,?,[,]对shell有特殊含义,但你可以用双引号引起来输入这些原形。



  讲了这么多大家是不是已经注意到所有的特殊字符在单引号中失去特殊含义,如果你要输出特殊字符原形但又记不清那些特殊字符在双引号中不能输出原形,建议你干脆用单引号引起来。



今天介绍条件测试语句



一、if 条件语句 



格式:

if 条件表达式

then #当条件为真时执行以下语句

命令列表

else #为假时执行以下语句

命令列表

fi



if 语句也可以嵌套使用



if 条件表达式1

then

if 条件表达式2

then

命令列表

else

if 条件表达式3

then

命令列表

else

命令列表

fi

fi

else

命令列表

fi



你可以进行多层嵌套,一个if语句一定要跟一个fi,表示该层条件结束否则会造成语法错误结合前面讲的,举例如下:

这里先讲一个条件语句中用到的命令test,表示测试test后面的条件是否为真?



if test -f "$1"

then

lpr $1

else

if test -d "$1"

then

cd $1

lpr $1

else

echo "$1不是文件或目录"

fi

fi



以上的例子还可以改成如下所示



if test -f "$1"

then

lpr $1

elif test -d "$1" #elif 同else if

then

(cd $1;lpr $1)

else

echo "$1不是文件或目录"

fi??????



以上的例子不知您是否看懂是什么意思吗?

假如我们现在将这个例子保存为prfile

chmod +x prfile

执行刚才的程序

./prfile aaa



这个例子是检查你的输入的参数是否是一个文件,如果是就打印,如果是一个目录,先转目录再打印,如果即不是文件也不是目录给出提示。



二、多重条件测试语句case



格式:

case 字串 in

模式) 命令列表;;

模式) 命令列表;;

....

esac



多重条件语句是以case 开始以esac结束,中间可以有多个条件列表,功能是测试字串和和里面的模式有没有匹配的,有就执行里面的命令列表,模式也可以是*号,表示任意字串,每个模式里面的最后要心;;双引号结束,否则会发生语法错误。



现举例如下:



case $1 in

*.c)

cc $1

;;

*.txt)

lpr $1

;;

*)

echo "未知的类型"

esac



假如将以上内容保存在文件abc中



chmod +x abc

执行 ./abc a.c   将会对文件a.c进行编译

执行 ./abc readme.txt 将会把文件通过打印机

假如我将以上内容改一下,你是否会知道它的执行结果?



case $1 in

*)

cc $1

;;

*.txt)

lpr $1

;;

*.c)

echo "未知的类型"

esac



今天介绍循环语句



一. while 循环



while 命令格式



while 条件表

do

命令表

done



执行过程



shell首先执行条件表,如果条件表的最后一条语句的退出状态为零,则执行盾环体内的命令表,执行完后,再检查条件表,如果退出状态为零将继续执行,如此循环往复直到条件表的最后一条语句的退出状态非零. 退出状态为零就是条件为真True.



举例说明 假如shell文件的内容如下:



Sum=0

i=0

while true #true是系统的关键词 表示真

do

i=`expr $i + 1`

Sum=`expr $Sum + $i`

if [ $i = "100" ]

then

break;

fi

done

echo $i $Sum

最后这个程序显示的是 100 5050这个程序的运算就是将1到100加起来



下面将这个程序再改动一下



Sum=0

i=0

while [ $i != "100" ]

do

i=`expr $i + 1`

Sum=`expr $Sum + $i`

done

echo $i $Sum



改动后的程序运算结果和上面是一样,但程序比上面的要简练。



在这个循环中还可以以until做为测试条件,它正好与while测试的条件相反,也就是当条件为假时将继续执行循环体内的语句,否则就退出循环体,下面还用这个例子.



Sum=0

i=0

until [ $i = "100" ]

do

i=`expr $i + 1`

Sum=`expr $Sum + $i`

done

echo $i $Sum



当i不等于100时循环 就是当条件为假时循环,否则就退出,而第一个例子是当i不等于100时循环,也就是测试条件为真时循环.



二.for 循环



命令格式:

for 变量 in 名字列表

do

命令列表

done



这里的名字列表是一个由空格分隔的字符串列表,shell在执行for循环时每次依次从名字表中取出一个字符串赋给循环变量作为变量的值.

在写for语句时,也可以省略in 名字列表部分,这表示用当前的位置参数来代替这时的名字列表.

下面举个例子

比如在你的电脑中有两个目录,一个是aa,一个是bb在这两个目录中有5个相同的文件,但其中一个目录中的一个或多个文件刚刚修改过,现在我忘记刚才改的是那几个文件了,那么我靠梢员冉弦幌抡饬礁瞿柯嫉奈募?椭?懒?程序如下:



for File in a1 a2 a3 a4 a5

do

diff aa/$File bb/$File

done



下面再举一个不带名字列表的例子



for File

do

echo $Filw

done



文件内容保存在a.sh中 并可执行我们在执行这个shell程序时命令行如下:

a.sh a1 a2 a3 a4 a5

执行结果如下:

a1

a2

a3

a4

a5

大家从这个例子中可以看到命令行的参数被逐一读入一次



三.循环控制语句



break 命令不执行当前循环体内break下面的语句从当前循环退出.

continue 命令是程序在本循体内忽略下面的语句,从循环头开始执行.



一,命令组合:



圆括号和花括号shell中有两种方法将命令组合在一起:圆括号和花括号.圆括号使shell创建一个子shell来读取并执行括起来的名命令.左括号和右括号不论出现在命令行中的什么位置,shell都会认为它们具有特殊的组合意义的.只有用双引号将它们括起来引用,才表示圆括号或花括号的原义.例如:



echo a(b)

将出现语法上的错误,要想输出a(b)字符串 只能括起来

echo "a(b)"

或echo a"("b")"

这样才能被shell正确解释.

利用组合命令有什么作用呢?



二,用圆括号组合命令



圆括号的组合命令可以创建子进程运行组合程序,建立子进程的功能是很有用的,因为子shell在组合命令中的种种操作都不会影响到当前shell的各变量的值.

例如:

子进程在执行组合命令时改变了工作目录,并在新的工作目录下执行一系例命令,执行完后它可以不必返回原工作目录,因为子进程工作目录的改变不会影响到当前工作目录.



创建子进程后将当前的环境也同样传给子shell,当前shell中用export输出到环境中的各变量在子shell中同样有效.



花括号也可以将命令组合在一起.左 右花括号只有作为一条命令的第一个字出现时,shell才它们含有特殊含义.



与圆括号不同的是花括号并不创建子shell,只是由当前的shell来读取并执行括起来的命令.有时用户希望使用一组命令的顺序输出作为另一组命令的输入,此时用花括号是很方便的. 不论是用圆括号不是花括号,退出状态都是等于最后一条括起来的命令的退出状态.



三,可以在当前shell中执行的命令



用户在使用shell时一定要了解那些是可以在当前shell中执行的命令,那些不可以在当前shell中执行的命令有:



break case cd continue

echo eval exec exit

export for if read

readonly return set shift

test times trap umask

until wait while
文章评论

共有 0 条评论