linux shellScripts-1
linux shellScripts-1
拉普兰德 发表于2年前
linux shellScripts-1
  • 发表于 2年前
  • 阅读 6
  • 收藏 0
  • 点赞 0
  • 评论 0

华为云·免费上云实践>>>   

摘要: 对谈式脚本read 数值运算 source, sh script, ./script test 命令的测试功能 利用判断符号 [ ] if .... then

对谈式脚本:变量内容由使用者决定

[root@www ~]# read [-pt] variable选项与参数:
-p  :后面可以接提示字符!
-t  :后面可以接等待的『秒数!』这个比较有趣~不会一直等待使用者啦!

declare / typeset

[root@www ~]# declare [-aixr] variable选项与参数:
-a  :将后面名为 variable 的变量定义成为数组 (array) 类型
-i  :将后面名为 variable 的变量定义成为整数数字 (integer) 类型
-x  :用法与 export 一样,就是将后面的 variable 变成环境变量;
-r  :将变量配置成为 readonly 类型,该变量不可被更改内容,也不能 unset

随日期变化:利用 date 进行文件的创建

数值运算:简单的加减乘除

可以使用『 declare -i total=$firstnu*$secnu 』

建议使用这样的方式来进行运算:

var=$((运算内容))
[root@www scripts]# echo $(( 13 % 3 ))
1

script 的运行方式差异 (source, sh script, ./script)

利用直接运行的方式来运行 script 当子程序完成后,在子程序内的各项变量或动作将会结束而不会传回到父程序中 子程序 bash 内的所有数据便被移除

                                                  sh02.sh 在子程序中运行

利用 source 来运行脚本:在父程序中运行

source 对 script 的运行方式可以使用底下的图示来说明! sh02.sh 会在父程序中运行的,因此各项动作都会在原本的 bash 内生效!这也是为啥你不注销系统而要让某些写入 ~/.bashrc 的配置生效时,需要使用『 source ~/.bashrc 』而不能使用『 bash ~/.bashrc 』是一样的啊!

                                                   sh02.sh 在父程序中运行

善用判断式

利用 test 命令的测试功能

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

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

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

[root@www ~]# test -e /dmtsai && echo "exist" || echo "Not exist"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 表示可读否 (但 root 权限常有例外)
-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 判断 file1 与 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

利用判断符号 [ ]

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

[root@www ~]# [ -z "$HOME" ] ; echo $?

使用中括号必须要特别注意,因为中括号用在很多地方,包括万用字节与正规表示法等等,所以如果要在 bash 的语法当中使用中括号作为 shell 的判断式时,必须要注意中括号的两端需要有空白字节来分隔喔! 假设我空白键使用『□』符号来表示,那么,在这些地方你都需要有空白键:

[  "$HOME"  ==  "$MAIL"  ]
[□"$HOME"□==□"$MAIL"□]
  • 在中括号 [] 内的每个组件都需要有空白键来分隔;

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

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

Shell script 的默认变量($0, $1...)

script 针对参数已经有配置好一些变量名称了!对应如下:

/path/to/scriptname  opt1  opt2  opt3  opt4 
       $0             $1    $2    $3    $4

运行的脚本档名为 $0 这个变量,第一个接的参数就是 $1 啊~ 所以,只要我们在 script 里面善用 $1 的话,就可以很简单的立即下达某些命令功能了!除了这些数字的变量之外, 我们还有一些较为特殊的变量可以在 script 内使用来呼叫这些参数喔!

  • $# :代表后接的参数『个数』,以上表为例这里显示为『 4 』;

  • $@ :代表『 "$1" "$2" "$3" "$4" 』之意,每个变量是独立的(用双引号括起来);

  • $* :代表『 "$1c$2c$3c$4" 』,其中 c 为分隔字节,默认为空白键, 所以本例中代表『 "$1 $2 $3 $4" 』之意。

shift:造成参数变量号码偏移

除此之外,脚本后面所接的变量是否能够进行偏移 (shift) 呢?什么是偏移啊?我们直接以底下的范例来说明好了, 用范例说明比较好解释!我们将 sh07.sh 的内容稍作变化一下,用来显示每次偏移后参数的变化情况:

[root@www scripts]# vi sh08.sh#!/bin/bash
# Program:
#	Program shows the effect of shift function.
# History:
# 2009/02/17	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

echo "Total parameter number is ==> $#"
echo "Your whole parameter is   ==> '$@'"
shift   # 进行第一次『一个变量的 shift 』echo "Total parameter number is ==> $#"
echo "Your whole parameter is   ==> '$@'"
shift 3 # 进行第二次『三个变量的 shift 』echo "Total parameter number is ==> $#"
echo "Your whole parameter is   ==> '$@'"

这玩意的运行成果如下:

[root@www scripts]# sh sh08.sh one two three four five six <==给予六个参数
Total parameter number is ==> 6   <==最原始的参数变量情况
Your whole parameter is   ==> 'one two three four five six'
Total parameter number is ==> 5   <==第一次偏移,看底下发现第一个 one 不见了
Your whole parameter is   ==> 'two three four five six'
Total parameter number is ==> 2   <==第二次偏移掉三个,two three four 不见了
Your whole parameter is   ==> 'five six'

条件判断式

利用 if .... then

  • 单层、简单条件判断式

如果你只有一个判断式要进行,那么我们可以简单的这样看:

if [ 条件判断式 ]; then
	当条件判断式成立时,可以进行的命令工作内容;fi   <==将 if 反过来写,就成为 fi 啦!结束 if 之意!

至於条件判断式的判断方法,与前一小节的介绍相同啊!较特别的是,如果我有多个条件要判别时, 除了 sh06.sh 那个案例所写的,也就是『将多个条件写入一个中括号内的情况』之外, 我还可以有多个中括号来隔开喔!而括号与括号之间,则以 && 或 || 来隔开,他们的意义是:

  • && 代表 AND ;

  • || 代表 or ;

所以,在使用中括号的判断式中, && 及 || 就与命令下达的状态不同了。举例来说, sh06.sh 里面的判断式可以这样修改:

[ "$yn" == "Y" -o "$yn" == "y" ]
上式可替换为
[ "$yn" == "Y" ] || [ "$yn" == "y" ]

之所以这样改,很多人是习惯问题!很多人则是喜欢一个中括号仅有一个判别式的原因。好了, 现在我们来将 sh06.sh 这个脚本修改成为 if ... then 的样式来看看:

[root@www scripts]# cp sh06.sh sh06-2.sh  <==用改的比较快![root@www scripts]# vi sh06-2.sh#!/bin/bash
# Program:
#       This program shows 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

if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
	echo "OK, continue"
	exit 0
fi
if [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
	echo "Oh, interrupt!"
	exit 0
fi
echo "I don't know what your choice is" && exit 0
  • 多重、复杂条件判断式

在同一个数据的判断中,如果该数据需要进行多种不同的判断时,应该怎么作?举例来说,上面的 sh06.sh 脚本中,我们只要进行一次 $yn 的判断就好 (仅进行一次 if ),不想要作多次 if 的判断。 此时你就得要知道底下的语法了:

# 一个条件判断,分成功进行与失败进行 (else)if [ 条件判断式 ]; then
	当条件判断式成立时,可以进行的命令工作内容;else
	当条件判断式不成立时,可以进行的命令工作内容;fi

如果考虑更复杂的情况,则可以使用这个语法:

# 多个条件判断 (if ... elif ... elif ... else) 分多种不同情况运行if [ 条件判断式一 ]; then
	当条件判断式一成立时,可以进行的命令工作内容;elif [ 条件判断式二 ]; then
	当条件判断式二成立时,可以进行的命令工作内容;else
	当条件判断式一与二均不成立时,可以进行的命令工作内容;fi

你得要注意的是, elif 也是个判断式,因此出现 elif 后面都要接 then 来处理!但是 else 已经是最后的没有成立的结果了, 所以 else 后面并没有 then 喔!好!我们来将 sh06-2.sh 改写成这样:

[root@www scripts]# cp sh06-2.sh sh06-3.sh[root@www scripts]# vi sh06-3.sh#!/bin/bash
# Program:
#       This program shows 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

if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
	echo "OK, continue"
elif [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
	echo "Oh, interrupt!"
else
	echo "I don't know what your choice is"
fi

是否程序变得很简单,而且依序判断,可以避免掉重复判断的状况,这样真的很容易设计程序的啦! ^_^! 好了,让我们再来进行另外一个案例的设计。一般来说,如果你不希望使用者由键盘输入额外的数据时, 可以使用上一节提到的参数功能 ($1)!让使用者在下达命令时就将参数带进去! 现在我们想让使用者输入『 hello 』这个关键字时,利用参数的方法可以这样依序设计:

  1. 判断 $1 是否为 hello,如果是的话,就显示 "Hello, how are you ?";

  2. 如果没有加任何参数,就提示使用者必须要使用的参数下达法;

  3. 而如果加入的参数不是 hello ,就提醒使用者仅能使用 hello 为参数。

整个程序的撰写可以是这样的:

[root@www scripts]# vi sh09.sh#!/bin/bash
# Program:
#	Check $1 is equal to "hello"
# History:
# 2005/08/28	VBird	First release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

if [ "$1" == "hello" ]; then
	echo "Hello, how are you ?"
elif [ "$1" == "" ]; then
	echo "You MUST input parameters, ex> {$0 someword}"
else
	echo "The only parameter is 'hello', ex> {$0 hello}"
fi

然后你可以运行这支程序,分别在 $1 的位置输入 hello, 没有输入与随意输入, 就可以看到不同的输出罗


共有 人打赏支持
粉丝 2
博文 34
码字总数 50893
评论 (0)
×
拉普兰德
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: