shell学习笔记三--脚本初步

上篇我们学习了 shell 脚本编程中常用的一些工具,从本篇开始,我们可以尝试编写自己的脚本了。我们依次来讨论以下几个主题:
 
创建脚本文件
变量
内部整数算术运算
 
一、创建脚本文件
创建并执行
shell 程序可以直接从终端上键入,如:
$who | wc �Cl
$
或者,也可以先把程序键入一个文件,然后由 shell 来执行这个文件。所要做的事情只有以下几步:
1   创建文件
2   将程序内容依次键入文件中
3   赋予该文件可以被执行的权限
下面演示创建一个 shell 脚本的完整过程 , 脚本的名字叫做 nu ,用于统计系统已登陆用户数。
$vi nu
who | wc �Cl
退出 vi 并保存。
$chmod +x nu
shell 脚本 nu 就创建好了,接下来的任务就是,执行这个脚本。
$./nu
4
$
结果表明,目前有 4 个用户登陆到系统上。
再写一个看起来稍微复杂一点点的脚本 stats 。这次我们打算完成的任务是,输出当前时间、已登陆用户数、当前工作目录。
$cat stats
date
who | wc �Cl
pwd
$chmod +x stats
$./stats
Mon Sep 28 14:04:47 EDT 2009
4
/root/testdir
$
从上面两个脚本,我们可以得到几个结论:只要把命令一条接一条写进脚本,执行时 shell 就按照顺序挨个执行他们,并输出结果;执行命令的时候只要输入脚本带路径的文件名就可以了( ./stats 是一个相对路径)。
注释
如果没有注释,那么 shell 脚本是不完整的,尽管注释对脚本的执行没有影响。维护一个没有任何注释的脚本,是件很痛苦的事。哪怕脚本是维护者自己写的,一段时间以后,也不能保证能完全理解以前写的脚本。
每当 shell 在看到特殊字符 # 后,就会将其后直到行尾的内容视为注释,直接将他们忽略。如果某行以 # 开头,那么 shell 将整行视为注释内容。下面有一些例子:
$cat stats
# Here is a entire commentary line
Date
 
who | wc �Cl    # count the number of users
 
pwd
 
# End of script
$
额外的空行几乎不占用什么程序空间,然而可以大大增加程序的可读性, shell 只是将他们忽略掉。
 
二、变量
与所有的变成语言一样, shell 也允许把值存在变量中。 Shell 变量名以字母或下划线字
符开始,后面跟 0 或若干个字母、数字或下划线字符。把值存入变量(俗称赋值)的格式为:
variable=value
例如,要把数值 1 赋值给 shell 变量 count ,只要写
count=1
要把值 /home/steve/bin 赋给 shell 变量 my_bin ,只要写
my_bin=/home/steve/bin
这里有几个关键点:
1 、等号的任何一边不能加空格;
2 Shell 没有任何数据类型的概念, shell 默认将所有赋给变量的值当作字符处理。此外, shell 可以根据上下文判断是字符还是数字。
显示变量的值
可以用 echo 命令显示变量的值:
$echo $count
1
$echo $my_bin
/home/steve/bin
$
也可以一次显示多个变量:
$echo $count $my_bin
1 /home/steve/bin
$
键入 echo $count 时, shell $count 替换为 count 所存入的值,然后执行 echo 命令;键入 echo $count $my_bin 时, sehll 先替换 $count $my_bin 的值,然后执行 echo 命令。
变量值可以用于命令行的任何地方,如:
$ls $my_bin
mon
nu
$
就是命令也能存在变量中:
$command=wc
$option=-l
$file=names
$$command $option $file
4 names
$
因为 sehll 在确定要执行的程序名及其参数之前进行替换,扫描命令行
$command $option $file
并转换成
wc �Cl names
然后再执行 wc ,并传递两个参数 -l names
空值
$echo :$nosuch:
: :
$
可以看到, shell 没有把 $nosuch 替换成任何值,因为我们并没有给变量 nosuch 赋过值。如果一个变量没有值,我们就说它含有空值,这是变量还没有赋值时的默认状态。当 shell 进行变量替换时,任何空值都被完全从命令行中被清除,不留一点痕迹。
文件名替换和变量
如果键入
x=*
执行命令 echo $x 会出现什么结果呢?我们来试试吧:
$ls
1.bak  2.bak  3.bak  urfile
$x=*
$echo $x
1.bak  2.bak  3.bak  urfile
$
替换的顺序是这样的:
x=* 将符号 * 存入变量 x 中,这一步并不将文件名清单替换出来
echo $x $x 替换成变量 x 的值,也就是 * ,得到 echo *
echo * shell 看到了 * ,所以先把 * 替换为当前目录文件名列表,再执行 echo
${variable} 结构
当我们键入
echo $count1
时, shell 会认为我们要显示变量 count1 的值,还是显示变量 count 的值后面跟 1 呢?答案是显示变量 count1 的值。那么如果我们想要显示 count 的值后面跟 1 ,应该怎么做呢? ${} 结构可以帮我们这个忙。看下面的例子:
$count=1
$count1=a
$echo $count1
a
$echo ${count}1
11
$
事实上, $count 也可以写成 ${count} ,只不过这时的 {} 不是必须的。一般情况,当你引用某个变量时,其后还紧跟其他字符,这时应该用 {} 把变量保护起来。
 
三、内部整数算术运算
Shell 有自己的执行算术运算的机制,称为算术扩展。算术扩展的格式是:
$((expression))
其中 expression 是由变量和运算符构成的算术表达式。下面的例子中,变量 a 开始是没有值的:
$echo $a
 
$echo $((a=a+1))
1
$echo $a
1
$
表达式还可以用括号来改变优先级,就像小学数学中学的那样:
echo $((i=(i+10)*j))
$a=$((a * 5))
$echo $a
5
$
有两点是需要我们注意的: 1 expression 中的变量替换不需要再用 $ 引用了,因为 (()) 外面已经有 $ 2 expression 中的空格是任选的,但是赋值放到小括号外的话,就不能有空格了。
expression 中还可以使用不等式:
result=$(( i >= 0 && i <= 100))
如果表达式的值为真,就给 result 1 ,否则给 result 0
$i=$(( 100 * 200 / 10 ))
$j=$(( i < 1000 ))
$echo $i $j
2000 0
$
 
本篇就介绍到这里了,关于引用、命令替换的内容将在下一篇中介绍。
本文出自 51CTO.COM技术博客
 
 

你可能感兴趣的:(shell,职场,休闲)