注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

技术行者

时代的车轮在按照摩尔定律滚动。

 
 
 

日志

 
 

Shell经典入门二(转)  

2011-03-02 15:32:00|  分类: Shell |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

数值运算的方法 

各位看官应该还记得,我们可以使用 declare 来定义变量的类型吧?! 这样才能够进行加减运算啊!可惜的是, bash shell 里头预设仅支持到整数的数据。 OK!那我们来玩玩看,如果我们要使用者输入两个变量,然后将两个变量的内容相乘, 最后输出相乘的结果,那可以怎么做?

[root@linux scripts]# vi sh04.sh

#!/bin/bash

# Program:

#         User can input 2 integer to cross by!

# History:

# 2005/08/23        VBird        First release

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

echo -e "You SHOULD input 2 number, I will cross they! "

read -p "first number:  " firstnu

read -p "second number: " secnu

total=$(($firstnu*$secnu))

echo -e " The number $firstnu x $secnu is ==>; $total"

在数字的运算上,我们可以使用『 declare -i total=$firstnu*$secnu 』 也可以使用上面的方式来进行!基本上,鸟哥比较建议使用这样的方式来进行运算: 

var=$((运算内容))

不但容易记忆,而且也比较方便的多~未来您可以使用这种方式来计算的呀!至于数值运算上的处理, 则有:+, -, *, /, %等等。 那个 % 是取余数啦~举例来说, 13 对 3 取余数,结果是 13=4*3+1,所以余数是 1 啊!就是:

[root@linux scripts]# nu=$((13%3)); echo $nu

1

这样了解了吧?!多多学习与应用喔! ^_^

--------------------------------------------------------------------------------

善用判断式

在 bash 章节中,我们提到过 $? 这个变量所代表的意义, 此外,也透过 && 及 || 来作为前一个指令是否能够成功进行的一个参考。 那么,如果我想要知道 /dmtsai 这个目录是否存在时,难道一定要使用 ls 来执行, 然后再以 $? 来判断执行成果吗?呵呵!当然不需要! 我们可以透过『 test 』这个指令来侦测呢!

--------------------------------------------------------------------------------

利用 test 指令的测试功能

当我要检测系统上面某些档案或者是相关的属性时,利用 test 这个指令来工作, 真是好用得不得了,举例来说,我要检查 /dmtsai 是否存在时,使用:

[root@linux ~]# test -e /dmtsai

执行结果并不会显示任何讯息,但最后我们可以透过 $? 或 && 及 || 来展现整个结果呢! 例如我们在将上面的例子改写成这样:

[root@linux ~]# test -e /dmtsai && echo "exist" || echo "Not exist"

最终的结果可以告知我们是『exist』还是『Not exist』呢!那我知道 -e 是测试一个『东西』在不在, 如果还想要测试一下该档名是啥玩意儿时,还有哪些标志可以来判断的呢?呵呵!有底下这些东西喔!

测试的标志 代表意义 

1. 关于某个档名的『类型』侦测(存在与否),如 test -e filename 

-e 该『档名』是否存在?(常用) 

-f 该『档名』是否为档案(file)?(常用) 

-d 该『文件名』是否为目录(directory)?(常用) 

-b 该『档名』是否为一个 block device 装置? 

-c 该『档名』是否为一个 character device 装置? 

-S 该『档名』是否为一个 Socket 档案? 

-p 该『档名』是否为一个 FIFO (pipe) 档案? 

-L 该『档名』是否为一个连结档? 

2. 关于档案的权限侦测,如 test -r filename 

-r 侦测该档名是否具有『可读』的属性? 

-w 侦测该档名是否具有『可写』的属性? 

-x 侦测该档名是否具有『可执行』的属性? 

-u 侦测该文件名是否具有『SUID』的属性? 

-g 侦测该文件名是否具有『SGID』的属性? 

-k 侦测该文件名是否具有『Sticky bit』的属性? 

-s 侦测该档名是否为『非空白档案』? 

3. 两个档案之间的比较,如: test file1 -nt file2 

-nt (newer than)判断 file1 是否比 file2 新 

-ot (older than)判断 file1 是否比 file2 旧 

-ef 判断 file2 与 file2 是否为同一档案,可用在判断 hard link 的判定上。 主要意义在判定,两个档案是否均指向同一个 inode 哩! 

4. 关于两个整数之间的判定,例如 test n1 -eq n2 

-eq 两数值相等 (equal) 

-ne 两数值不等 (not equal) 

-gt n1 大于 n2 (greater than) 

-lt n1 小于 n2 (less than) 

-ge n1 大于等于 n2 (greater than or equal) 

-le n1 小于等于 n2 (less than or equal) 

5. 判定字符串的数据 

test -z string 判定字符串是否为 0 ?若 string 为空字符串,则为 true 

test -n string 判定字符串是否非为 0 ?若 string 为空字符串,则为 false。

注: -n 亦可省略 

test str1 = str2 判定 str1 是否等于 str2 ,若相等,则回传 true 

test str1 != str2 判定 str1 是否不等于 str2 ,若相等,则回传 false 

6. 多重条件判定,例如: test -r filename -a -x filename 

-a (and)两状况同时成立!例如 test -r file -a -x file,则 file 同时具有 r 与 x 权限时,才回传 true。 

-o (or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 或 x 权限时,就可回传 true。 

! 反相状态,如 test ! -x file ,当 file 不具有 x 时,回传 true 

OK!现在我们就利用 test 来帮我们写几个简单的例子。首先,判断一下, 让使用者输入一个档名,我们判断:

这个档案是否存在,若不存在则给予一个『Filename does not exist』的讯息,并中断程序; 

若这个档案存在,则判断他是个档案或目录,结果输出『Filename is regular file』或 『Filename is directory』 

判断一下,执行者的身份对这个档案或目录所拥有的权限,并输出权限数据!

你可以先自行创作看看,然后再跟底下的结果讨论讨论。注意利用 test 与 && 还有 || 等标志!

[root@linux scripts]# vi sh05.sh

#!/bin/bash

# Program:

#         Let user input a filename, the program will search the filename

#        1.) exist? 2.) file/directory? 3.) file permissions 

# History:

# 2005/08/25        VBird        First release

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

# 1. 让使用者输入档名,并且判断使用者是否真的有输入字符串?

echo -e "The program will show you that filename is exist which input by you. "

read -p "Input a filename : " filename

test -z $filename && echo "You MUST input a filename." && exit 0

# 2. 判断档案是否存在?

test ! -e $filename && echo "The filename $filename DO NOT exist" && exit 0

# 3. 开始判断档案类型与属性

test -f $filename && filetype="regulare file"

test -d $filename && filetype="directory"

test -r $filename && perm="readable"

test -w $filename && perm="$perm writable"

test -x $filename && perm="$perm executable"

# 4. 开始输出信息!

echo "The filename: $filename is a $filetype"

echo "And the permission are : $perm"

很有趣的例子吧!您可以自行再以其它的案例来撰写一下可用的功能呢!

--------------------------------------------------------------------------------

利用判断符号 [ ]

除了我们很喜欢使用的 test 之外,其实,我们还可以利用判断符号『 [ ] 』来进行数据的判断呢! 举例来说,如果我想要知道 $HOME 这个变量是否为空的,可以这样做:

[root@linux ~]# [ -z "$HOME" ]

但使用 [] 要特别注意的是,在上述的每个组件中间都需要有空格键来分隔,假设我空格键使用『□』来表示, 那么,在这些地方你都需要有空格键:

[  "$HOME"  ==  "$MAIL"  ]

[□"$HOME"□==□"$MAIL"□]

↑       ↑  ↑       ↑

上面的例子在说明,两个字符串 $HOME 与 $MAIL 是否相同的意思,相当于 test $HOME = $MAIL 的意思啦! 而如果没有空白分隔,例如 [$HOME==$MAIL] 时,我们的 bash 就会显示错误讯息了!这可要很注意啊! 所以说,您最好要注意:

在中括号 [] 内的每个组件都需要有空格键来分隔; 

在中括号内的变量,最好都以双引号来设定; 

在中括号内的常数,最好都以单或双引号来设定。

举例来说,假如我设定了 name="VBird Tsai" ,然后这样判定:

[root@linux ~]# name="VBird Tsai"

[root@linux ~]# [ $name == "VBird" ]

bash: [: too many arguments

为什么呢?因为 $name 如果没有使用双引号刮起来,那么上面的判定式会变成: 

[ VBird Tsai == "VBird" ] 

而不是我们要的: 

[ "VBird Tsai" == "VBird" ] 

这可是差很多的喔!另外,中括号的使用方法与标志与 test 几乎一模一样啊~ 只是中括号比较常用在条件判断式 if ..... then ..... fi 的情况中就是了。 好,那我们也继续来做一个小案例好了:

当执行一个程序的时候,这个程序会让使用者选择 Y 或 N , 

如果使用者输入 Y 或 y 时,就显示『 OK, continue 』 

如果使用者输入 n 或 N 时,就显示『 Oh, interrupt !』 

如果不是 Y/y/N/n 之内的其它字符,就显示『I don't know what is your choise』

利用中括号、 && 与 || 来继续吧!

[root@linux scripts]# vi sh06.sh

#!/bin/bash

# Program:

#         This program will show the user's choice

# History:

# 2005/08/25        VBird        First release

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

read -p "Please input (Y/N): " yn

[ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK, continue" && exit 0

[ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh, interrupt!" && exit 0

echo "I don't know what is your choise" && exit 0

很有趣吧!利用这个字符串判别的方法,我们就可以很轻松的将使用者想要进行的工作分门别类呢! 接下来,我们再来谈一些其它有的没有的东西吧!

Tips:

为什么判断式里面下达等于要用 == 而不是一个 = 就好了呢?我们在前一章正规表示法里面的 awk 提到, 只有一个 = 用来给予一个变量设定其内容,逻辑判断时,则会给予两个等于, 亦即『比较』而非『设定』的意思~这里要好好的分辨一下喔! ^_^   

--------------------------------------------------------------------------------

Shell script 的预设变数($0, $1...)

其实,当我们执行一个 shell script 时,在这个 shell script 里面就已将帮我们做好一些可用的变量了。 举例来说,在不久的将来,您就会发现,当我们要启动一个系统服务时,可能会下达类似这样的指令:

[root@linux ~]# /etc/init.d/crond restart

那是啥玩意儿?呵呵!就是『向 /etc/init.d/crond 这个 script 下达 restart 的指令』, 咦!我们不是都使用 read 来读取使用者输入的变量内容吗?为啥我可以直接在 script 后面接上这个参数? 这是因为 shell script 帮我们设定好一些指定的变量了!变量的对应是这样的:

/path/to/scriptname  opt1  opt2  opt3  opt4  ...

       $0             $1    $2    $3    $4   ...

这样够清楚了吧?!执行的文件名为 $0 这个变量,第一个接的参数就是 $1 啊~ 所以,只要我们在 script 里面善用 $1 的话,就可以很简单的立即下达某些指令功能了! 好了,来做个例子吧~假设我要执行一个 script ,执行后,该 script 会自动列出自己的档名, 还有后面接的前三个参数,该如何是好?

[root@linux scripts]# vi sh07.sh

#!/bin/bash

# Program:

#         The program will show it's name and first 3 parameters.

# History:

# 2005/08/25        VBird        First release

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

echo "The script naem is ==>; $0"

[ -n "$1" ] && echo "The 1st paramter is ==>; $1" || exit 0

[ -n "$2" ] && echo "The 2nd paramter is ==>; $2" || exit 0

[ -n "$3" ] && echo "The 3th paramter is ==>; $3" || exit 0

这支程序里面鸟哥加上了一些控制式,亦即利用 && 及 || 来加以判断 $1 ~ $3 是否存在? 若存在才显示,若不存在就中断~执行结果如下:

[root@linux scripts]# sh sh07.sh theone haha quot

The script naem is ==>; sh07.sh

The 1st paramter is ==>; theone

The 2nd paramter is ==>; haha

The 3th paramter is ==>; quot

上面这七的例子都很简单吧?几乎都是利用 bash 的相关功能而已~ 不难啦~底下我们就要使用条件判断式来进行一些分别功能的设定了,好好瞧一瞧先~ 

--------------------------------------------------------------------------------

  评论这张
 
阅读(2451)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017