>> 欢迎您, 傲气雄鹰: 重登陆 | 退出 | 注册 | 资料 | 设置 | 排行 | 新贴 | 精华 | 管理 | 帮助 首页

  小榕软件实验室
  刀光雪影
  UNIX Shell Script
发表文章 发表涂鸦
  回复数:4  点击数:190 将此页发给您的朋友        
作者 主题: UNIX Shell Script 回复 | 收藏 | 打印 | 篇末
扑街帅哥哦
级别:管理员
威望:4
经验:134
货币:6128
体力:100
来源:青山精神病院
总发帖数:2271
注册日期:2001-07-23
查看 邮件 主页 QQ 消息 引用 复制 下载 

UNIX Shell本身是一个交谈式的命令环境,也是一个功能强大的译式程式语言(Interpreter)。一般我们称以UNIX Shell 写成的程式为Shell Script。不同的Shell语法,会有一定程度的差异。


Borne Shell(/bin/sh)是UNIX作业系统中最早存在的Shell,在所有的UNIX版本中均可发现他的存在,Borne Shell的语法适合Shell命令程式的写作。


UNIX Shell Script 的内容为UNIX指令与一些控制及回圈指令的组合。


UNIX Shell Scirpt的第一行开头为符号"#!"加上所用Shell名称,其用意为告诉kernel,这是一个可执行的程式,同时执行时的环境为所指定的shell(缺少这一行,执行时可能会遭遇到不可预期的错误)。


Shell Script是一种"Free Format"的程式,除了控制回圈须注意结构完整性外,程式本身并无特殊的格式。下面是一个Borne Shell的例子:

#!/bin/sh
echo " This is a Borne Shell Script "

(为使你的Shell Script可以执行,你必须将这个Shell Script的执行权限"x"打开 : chmod +x shell_script)

关于变数

设定变数方式为
var=value


取用变数的方法为
$var

Exmaple 1:
#!/bin/sh
woody="吴贤明 的小名"
echo $woody


(local)变数的设定,会在在同一个process中持续存在,一直到此process结束。


Shell中,变数的值可以含有space的字串,带有一个以上space的的变数,给定值的时候,必须以成对的双引号( " )或单引号(')涵盖之。



双引号( " )中若含有变数($var),会先将变数转换成其实际的值,单引号(')则会将$var当成是一个值,而不会作转换动作。

Example 2:
1. echo "woody就是 $woody"
2. echo 'woody就是 $woody '

结果:
1.woody 就是 吴贤明 的小名
2.woody 就是 $woody


Borne Shell中的内定变数
变数 变数意义
$# Number of arguments on the command line
$- Shell 的选项
$? Exit value of the last command executed ( in general, 0代表执行无误,1代表指令有误)
$$ Process number of the current process
$n Command line 中的参数,$0代表指令名称,$1代表第一个参数,$2代表第二个参数....
$* Command line 中的所有参数


Example 3:
Shell Script : var_test
#!/bin/sh
echo $#
echo $-
echo $?
echo $$
echo $0
echo $1
echo $2
echo $*

执行 var_test 1 2 3 4 5
结果? (Try it !!)

讯息列印

echo 指令可以让你一次在银幕上列印出一行字串(with Double quote‘"’ or Single quote‘'’),以下的方式可以让你一次印出一段文章:

Example 4:
#!/bin/sh
var1="变数一"
var2="变数二"
cat << SEGMENT1
Strings between the two "SEGMENT1"s will be treated as
constant,and printed out from the monitor。Variables between
these two SEGMENT1's will be calculated before any processing。
Yo umay try the following:
var1=$var1
var2=$var2
SEGMENT1

Another Example:

cat << \SEGMENT2 ##<--请注意这行中的符号‘\’
这是避免变数被解释的方法,请注意义以下字串被列印
出来的结果:
var1=$var1
var2=$var2
SEGMENT2

这个程式执行的结果为:
Strings between the two "SEGMENT1"s will be treated as
constant,and printed out from the monitor。Variables between
these two SEGMENT1's will be calculated before any processing。
Yo umay try the following:
var1=变数一
var2=变数二
Another Example:
这是避免变数被解释的方法,请注意义以下字串被列印
出来的结果:
var1=$var1
var2=$var2



read - 从银幕读入一个变数
Example 5:
#!/bin/sh
echo -e "Please input your name: \c" #(\c迫使游标不换行)
read name
echo "Hello, $name"



if 指令
Borne Shell中,if指令的用法为
if condition
then
command(s)
[elif condition
then command(s)]
[else
command(s)]
fi
中括号([])表示可有可无。

Example 6:
#!/bin/sh
ls -l /etc/host.conf
if [$? -eq 0] 注
then
echo "/etc/host.conf is there !!"
else
echo "/etc/host.conf is not there !!"
fi

注[$var -op value]可以比对$var与value ($var为数值变数)。op的值有gt (greater then),eq(equal to ),lt(less than),ge (greater than or equal to ),ne(not equal)及le(less than or qual to)。



test指令 (or [])
if控制回圈中的condition值只有真(0)与伪(none zero)两种,test指令(or [])提供了判断真与假的功能。

test可提供档名、字串与数值等真与伪的判断

档名
test -options file_name or [-option file_name]
常用option与其所代表的意义如下:
-r
True if file exists and readble
-w
True if file exists and writadble
-x
True if file exists and executadble
-f
True if file exists and is a regular file
-d
True if file exists and is a directory
-u
True if file exists and is setuid
-s
True if file exists and is greater than zero in size

字串 test -option string or [-option string]
常用option与其所代表的意义如下:
-z
True if string length is zero
-n
True if string length is non-zero
test string1 = string2 or [string1 = string2]
* True if string1 is identical to string2
test string1 != string2 or [string1 != string2]
--> True if string1 is not identical to string2

数值 test n1 -op n2 or [n1 -op n2]
常用op(运算元)与其所代表的意义如下
-eq
True if n1and n2 are equal
-ne
True if n1and n2 are not equal
-gt
True if n1 is greater than n2
-ge
True if n1 is greater than or equal tp n2
-lt
True if n1 is less than n2
-le
True if n1 is less than or equal to n2
** Both n1 & n2 are intergers



Case 指令(Conditional Swith)

case 指令的语法
case variable in
pattern1[|pattern1a]) commands ;;
pattern2) commands;;
....
*) commands ;;
esac

Example 7:
#!/bin/sh
cat << EOF
****************************************
a.I need a banana.
b.I need an orange.
c.I need an apple.
****************************************
EOF
read choice
case $choice in
a|A) echo "You need a banana !!" ;;
b|B) echo "You need an orange !!" ;;
c|C) echo "You need an apple !!" ;;
*) echo "Bad choice, see yo next time !!";;
esac


while 指令
while 指令语法
while condition
do
commands
done
##回圈中commands会一直被重复执行直到condition 的值为伪为止。

Example 8:计算从1加到10并把结果印出
#!/bin/sh
NO=11
START=1
SUM=0
while [ $NO -gt 0 ]
do
SUM=****expr $START + $SUM****
START=****expr $START + 1****
NO=****expr $NO - 1****
done
echo "The answer is $SUM"

说明:
1. Shell中把所有变数均当成字串,因此进行整数运算时,必须特别注明。内建function "expr"可以帮我们进行这样的数值计算。
2. 符号 **** 代表在变数给定的运算式中,带有指令或函数。设定变数必须先行运算,再做设定。例如
HOSTNAME=****/bin/hostname****
则$HOSTNAME的值会是指令/bin/hostname执行的结果


until 指令
until 指令语法
until condition
do
commands
done
##until指令用法与while恰巧相反;回圈中commands会一直被重复执行直
到condition 的值为真。
请试著以until重写上面数字累加的例子。

 

trap - Trapping Signal

Signal 是UNIX系统中用来传递控制讯息(由一程序到另一程序)的一种机制。

一个Process收到signal之后,会优先处理(将控制权交出),处理完毕之后在行返回元程序继续执行(重新取回控制权)。

Signal为一非同步讯息,由数字所构成。不同的数字所代表不同的控制讯息及不同的处理步骤,例如signal "2" (按下Ctrl+C"会送出这个讯号)代表结束目前程序。Programmer也可以在程式撰写时,重新定义Signal。‘trap’是在bash环境下,可供程式撰写者重设SIgnal的工具。

利用shell programming撰写程式时,使用trap通常是希望能够避免使用者以不正常方式中断程式,而使程式进入一个不可知的状态,危害到系统运作,或取得不正当的存取权限。UNIX Signal种类,及所代表的意义,请参考讲义‘UNIX Process’。常用的HotKey与Signal的对应如下:
Ctrl+C 2
Ctrl+\ 3
Ctrl+Z 20

trap格式
trap 'commands; command' signal_number
当程序收到"signal_number"时,会屏除系统预设处理步骤,改以执行单引号中的指令代之。
Example:
trap 'echo "Why You Use Ctrl+C ? Don't Do That Again !!!" 1
如果你在shell script中(程式最上头)加上这行指令,则当使用者(这执行这个程式时)按下Ctrl+C(预设动作为结束程式),银幕上会印出"Why You Use Ctrl+C ? Don't Do That Again !!!",并继续程式的执行。



Example :9 以下的例子是一个交谈式的新帐号建立程式

#!/bin/sh
ID=****whoami****
if [ $ID != "root" ]
then
cat << SEGMENT1

***********************************************

你不是系统管理者!!

这个程式以交谈式方式帮你建立使用者帐号,
你必须具备SuperUser权限。

***********************************************

SEGMENT1
exit 1
fi

echo -e "\n\n请输入使用者帐号:\c"
read login
echo -e "\n请输入使用者姓名:\c"
read comment
echo -e "请输入使用者密码(你将看不到你的输入):\c"
password=****./inp****

# "inp"是Woody老师写的一只小小程式,功能在避免
# 使用者key-in文字在银幕Show出,Source请参见nmc anonymous
# ftp linux目录下的inp.c,Compile with " cc -o inp inp.c "

echo -e "请再输入一次:\c"
password1=****./inp****

if [ $password != $password1 ]
then
echo "两次输入密码不一致,请再试一次"
exit 1
fi

adduser -c $comment $login

if [ $? -eq 0 ]
then
echo "Account $login Created !"
echo "$login:$password"|chpasswd

#chpasswd是系统指令,读入"username:password" Pair(From File),将帐号"username"的密码改成"password"

else
echo "Account Not Created !! "
fi

echo"";echo ""




Example :10 以下的例子是一个交谈式的使用者帐号密码更改程式(This Program is for root only!)

#!/bin/sh
trap "" 2 3 20
echo -e "\n\n\n"

if [ ! -x /usr/sbin/inp ]
then
echo -e "/usr/sbin/inp Needed, Please CHECK IT OUT !!!\n\n\n"
exit 1
fi

echo -e "请输入你要更改密码的帐号: \c"
LOGNAME=****whoami****
read login
if [ $LOGNAME != "root" ]
then
echo "You are Not Authorized to change OTHER'S Passwprd ...!"
exit 1
fi

grep ^$login":" /etc/passwd > /dev/null

if [ $? -eq 0 ]
then
echo -e "You New Password ....:\c"
passwd=****/usr/sbin/inp****
echo -e "You New Password Again....:\c"
passwdagain=****/usr/sbin/inp****
if [ $passwd = $passwdagain ]
then
echo "$login":"$passwd" | /usr/sbin/chpasswd
if [ $? -eq 0 ]
then
echo "Passwdord For $login Changed !"
else
echo "Password Not Changed, Please Try again !"
fi
else
echo "Password Not Match, Please Try Again.."
fi
else
echo "User Not Exist, Please Check it OUt !"
fi

echo -e "\n\n\n"




Exercise:
1. 请将讲义Example 1~ 8亲自做一次,并确实了解其语意(Know HOW)。
2. token=super
请问下面指令会得到什么结果?你知道为何如此吗?
echo $tokenman
echo '$token'man
echo "$token"man
3. 请写一shell script
(1).提示使用者选择1.可连(telnet)至ccsun, 2.可连(telnet)至bbs, 3. 可连(telnet)至nmc.nchu.edu.tw
(2).从键盘(keyboard)读取变数‘Choice’
(3).IF Choice=1 --> telnet to ccsun
IF Choice=2 --> telnet to bbs
IF Cjoice=3 --> telent to nmc.nchu.edu.tw
Otherwise Say something to user, and terminate the program
4. 请重新改写Example 8 with command "until" !
5. 请写一个shell script:
(1).提示使用者输入username
(2).若此user存在,输出‘此使用者存在,请输入下一笔资料’
(3).若此user不存在,输出‘此使用者不存在,请重新输入’
(4).若输入为Esc键,则跳离此一程式。
提示:
(1).grep username /etc/passwd可检查该user是否存在。
(2).echo $?可以检查上一个指令是否执行成功。
(3).输入特殊符号(或Hot Key)的方式为^v + Hot-key


(选自电子工业出版社《UINX使用大全》,如需转载,请注明出处)


[ 此消息由 扑街 在 2002-10-15.01:37:46 编辑过 ]
----------------------------------------------------------
今生无缘,泪如雨下,我试着忘记红尘中你留下的故事,可数日以来我始终无法走出你曾给我的感情世界,我深知让往事随风不是说说那么容易的. 天空下我们彼此站成了两个无法相溶的世界我却又总想忍住悲伤,而思念像穿透了灵魂一般不可抑制

编辑 删除 发表时间发表于 2002-10-15.01:11:02   MSIE 6.0b Windows 98IP: 已记录
痞菜帅哥哦
级别:管理员
威望:9
经验:18
货币:99999
体力:100
来源:不知道
总发帖数:2602
注册日期:2001-04-13
查看 邮件 主页 QQ 消息 引用 复制 下载 

靠 你把shell编程的弄这干什么?加精
----------------------------------------------------------

哈哈

编辑 删除 发表时间发表于 2002-10-15.03:16:58   MSIE 5.01 Windows 2000IP: 已记录
扑街帅哥哦
级别:管理员
威望:4
经验:134
货币:6128
体力:100
来源:青山精神病院
总发帖数:2271
注册日期:2001-07-23
查看 邮件 主页 QQ 消息 引用 复制 下载 

嘎嘎,这玩意儿挺好的~~~嘎嘎,打到我手痛~~
----------------------------------------------------------
今生无缘,泪如雨下,我试着忘记红尘中你留下的故事,可数日以来我始终无法走出你曾给我的感情世界,我深知让往事随风不是说说那么容易的. 天空下我们彼此站成了两个无法相溶的世界我却又总想忍住悲伤,而思念像穿透了灵魂一般不可抑制

编辑 删除 发表时间发表于 2002-10-15.09:51:21   MSIE 6.0b Windows 98IP: 已记录
沉睡不醒帅哥哦
级别:老 站 友
威望:0
经验:0
货币:1026
体力:64.2
来源:61.188.139.*
总发帖数:256
注册日期:2002-04-02
查看 邮件 主页 QQ 消息 引用 复制 下载 

收藏~!

编辑 删除 发表时间发表于 2002-10-17.16:23:47   MSIE 5.0 Windows 98IP: 已记录
神来一笔帅哥哦
级别:高级站友
威望:1
经验:0
货币:755
体力:55
来源:218.11.92.*
总发帖数:175
注册日期:2002-10-07
查看 邮件 主页 QQ 消息 引用 复制 下载 

UNIX咱们不懂怎么办??
看不懂,不过可以来给捧捧场
嘿嘿!~!~

编辑 删除 发表时间发表于 2002-10-17.16:30:25   MSIE 5.01 Windows 2000IP: 已记录
选择回复        
 快速回复主题: >>>高级模式
  用户名: 没有注册? 密码: 忘记密码?
记住密码
HTML语法
禁止IDB代码
禁止表情字符

[按 Ctrl+Enter 快捷键可直接提交帖子]
 投票评分: 共 0 票  
所有时间均为: 北京时间 ↑TOP 
关闭主题 拉前主题 移动主题 主题置顶 取消置顶 总固顶主题 取消总固顶 加入精华 移出精华 删除主题