关键词:条件测试、条件测试类型、组合条件测试、向脚本传递参数、位置变量、特殊变量、选择执行语句(if单分支与双分支);
1、bash shell 脚本通用格式
[root@localhost tmp]# more first.sh #!/bin/bash # descriptions: # version:V1.0 # author:Fitz<fitz@kouyuushinn.cn> # date:2018-05-05 [root@localhost tmp]#
NOTE: 在脚本中的各个应用段落中必须添加脚本注释,说明此段脚本的功用;
2、条件测试
判断某需求是否满足,需要由测试机制来实现;
测试表达式的方式
>> 执行命令,并利用命令状态返回值来判断;
0 : 表示成功;
1-255 : 表示失败;
>> 测试表达式
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
3、bash的测试类型
3.1 数值测试(双目测试类型)
-eq : 是否等于; [ $num1 -eq $num2 ] , 注意中括号内部前后2端都是有空格的;
-ne : 是否不等于;
-gt : 是否大于;
-ge : 是否大于等于;
-lt : 是否小于;
-le : 是否小于等于;
3.2 字符串测试(双目测试类型)
== : 是否等于;
> : 是否大于;
< : 是否小于;
!= : 是否不等于;
=~ : 左侧字符串是否能够被右侧的PATTERN所匹配;做部分匹配;
单目测试类型:
-z “STRING” : 判断指定的字符串是否为空,空则为真,不空则为假;
-n “STRING” : 判断指定的字符串是否为不空,不空则为真,空则为假;
字符串测试注意事项:
字符串需要用引号;
单纯的字符串比较时,使用双中括号;[[ “STRING1” == “STRING2” ]];
带条件判断的语句时,使用单中括号;[ EXPRESSION == EXPRESSION ]; 此种情况的举例在”组合条件测试”中;
脚本的状态返回值,默认是脚本中执行的最后一条命令的状态返回值;
在脚本中可自定义状态码,exit [n] : 数字n为自定义的;
shell进程遇到”exit”时,进程即会终止;
3.3 文件测试(单目测试类型)
>> 存在性测试:
-a FILE : 文件的存在性测试,存在则为真,否则为假;
-e FILE : 文件的存在性测试,存在则为真,否则为假;
>> 存在性及类型测试:
-b FILE : 是否存在并且为 块设备 文件;如果存在且为 块设备 文件,则为真,否则(如果存在,但不是块设备文件)为假;真假判断,下面相同;
-c FILE : 是否存在并且为 字符设备 文件;
-d FILE : 是否存在并且为 目录 文件;
-f FILE : 是否存在并且为 普通文件;
-h FILE 或 -L FILE : 是否存在并且为 符号链接文件;
-p FILE : 是否存在并且为 管道文件;
-S FILE : 是否存在并且为 套接字文件;注意,是大写字母”S”;
>> 存在性及文件权限测试:
-r FILE : 是否存在并且对当前用户可读;如果存在并且对当前用户可读,则为真,否则(如果存在,但对当前用户的权限不可读)为假;
-w FILE : 是否存在并且对当前用户可写;
-x FILE : 是否存在并且对当前用户可执行;
>> 特殊权限测试:
-u FILE : 是否存在并且 拥有suid权限;存在且有suid权限,则为真;存在,但没有suid权限,则为假;
-g FILE : 是否存在并且 拥有sgid权限;
-k FILE : 是否存在并且 拥有sticky权限;
>>从属关系测试:
-O FILE : 是否存在,并且,当前用户是否为文件的属主;存在,且当前用户是文件的属主,则为真;存在,但当前用户不是文件的属主,则为假;
-G FILE : 是否存在,并且,当前用户是否属于文件的属组;
>> 时间戳测试:
-N FILE : 文件是否存在,并且自上一次读操作后是否被修改过;存在,且自上一次读操作后修改过,则为真;存在,但自上次读操作后未做修改,则为假;
>> 文件是否有内容测试:
-s FILE : 文件存在并且是否有内容;存在且有内容,则为真;存在但无内容,则为假;
>> 双目测试:
FILE1 -ef FILE2 : FILE1与FILE2是否指向同一个文件系统的相同的inode的硬链接;
FILE1 -nt FILE2 : FILE1是否新于FILE2;
FILE1 -ot FILE2 : FILE1是否旧于FILE2;
4、组合条件测试
逻辑运算的组合条件测试,第一种方式:
COMMOND1 && COMMOND2 与运算
COMMOND1 || COMMOND2 或运算
!COMMOND
逻辑运算的组合条件测试,第二种方式:
EXPRESSION1 -a EXPRESSION2
EXPRESSION1 -o EXPRESSION2
!EXPRESSION
举例:组合条件测试
将当前主机名称保存至hostName变量中;主机名如果为空,或者为localhost.localdomain,或者为localhost,则将主机名设置为kouyuushinn.cn;
[root@localhost tmp]# hostName="$HOSTNAME" [root@localhost tmp]# [root@localhost tmp]# [ -z "$hostName" -o "$hostName" == "localhost.localdomain" -o "$hostName" == "localhost" ] && hostnamectl set-hostname kouyuushinn.cn [root@localhost tmp]# hostname kouyuushinn.cn [root@localhost tmp]#
5、向脚本传递参数
变量有5种类型:
本地变量 : 作用域仅为当前shell进程;
环境变量 : 作用域为当前shell进程及其子进程;
局部变量 : 作用域仅为某代码片段(函数上下文);
位置参数变量 : 向执行脚本的shell进程传递的参数;
特殊变量 : shell内置的有特殊功用的变量;
5.1 位置参数变量的变量引用方式
$1 : 表示脚本中传递的第一个参数变量;
$2 : 表示脚本中传递的第二个参数变量;
$3 : 依次类推;
传递的参数变量的轮替:
shift [n] : 位置参数轮替,默认踢掉第一个参数变量,可指定数字,表示踢掉前面”n”个参数变量;
举例1:
传递2个参数变量给脚本,参数变量是2个文件,计算2个文件的空白行的行数之和;
#!/bin/bash # count_file1=$(grep "^[[:space:]]*$" $1 | wc -l) shift count_file2=$(grep "^[[:space:]]*$" $1 | wc -l) count_file_sum=$[$count_file1+$count_file2] echo "coung_file_sum is: $count_file_sum."
5.2 特殊变量
$0 : 脚本文件路径本身;
$# : 脚本参数的个数(数量);
$* : 列出脚本的所有参数,各个参数是独立的字符串;
$@ : 列出脚本的所有参数,所有参数做为一个字符串;
举例2:
#!/bin/bash # [ $# -lt 2 ] && echo "arg is requit two files." && exit 11 count_file1=$(grep "^[[:space:]]*$" $1 | wc -l) shift count_file2=$(grep "^[[:space:]]*$" $1 | wc -l) count_file_sum=$[$count_file1+$count_file2] echo "coung_file_sum is: $count_file_sum."
6、过程式编程语言的代码执行顺序的类型
顺序执行:代码逐条执行;
选择执行:代码只有一个分支,条件满足时才会执行;代码有2个或以上分支,只会执行其中一个满足条件的分支;
循环执行:代码片段(循环体)要执行0、1或多个来回;
7、选择执行
>> 单分支if语句:
if 测试条件;then
代码分支
fi
双分支if语句:
if 测试条件;then
条件为真时执行的分支
else
条件为假时执行的分支
fi
[root@kouyuushinn tmp]# [root@kouyuushinn tmp]# more third.sh #!/bin/bash # if [ $# -lt 1 ];then echo "at least one username." exit 11 elif [ $# -ge 2 ];then echo "requit only one username." exit 22 elif ! grep "^$1\>" /etc/passwd &> /dev/null;then useradd $1 echo "$1" | passwd --stdin $1 &> /dev/null echo "add user $1 is finished. user $1 password is $1." else echo "$1 is already exits." fi [root@kouyuushinn tmp]# [root@kouyuushinn tmp]# ./third.sh at least one username. [root@kouyuushinn tmp]# [root@kouyuushinn tmp]# ./third.sh user01 user02 requit only one username. [root@kouyuushinn tmp]# [root@kouyuushinn tmp]# ./third.sh user01 add user user01 is finished. user user01 password is user01. [root@kouyuushinn tmp]#
举例,通过命令行参数给定2个数字,输出其中较大的数值;
脚本1:只判断了参数个数,未对参数是否整数进行判断; #!/bin/bash # if [ $# -lt 2 -o $# -gt 2 ];then echo "need two integers." exit 22 fi if [ $1 -ge $2 ];then echo "max num is $1." else echo "max num is $2." fi 脚本2:只判断了参数个数,未对参数是否整数进行判断; #!/bin/bash # declare -i max=$1 if [ $# -lt 2 -o $# -gt 2 ];then echo "need two integers." exit 22 fi if [ $1 -lt $2 ];then max=$2 fi echo "max num is $max."
通过命令行参数给定1个用户名,判断其ID号是偶数还是奇数;
先判断参数个数;
再判断参数(用户)是否存在,如果存在,则输出UID号,对此UID号进行取模运算,判断是偶数还是奇数;
如果判断用户不存在,则创建用户,取出UID号,并对此UID号进行取模运算,判断是偶数还是奇数;
#!/bin/bash # if [ $# -lt 1 -o $# -gt 1 ];then echo echo "need one arg." exit 11 fi id $1 &> /dev/null if [ $? -eq 0 ];then echo echo "user $1 is already exits.it's UID : `id -u $1`." else echo echo "user $1 is not exits.create user $1 now..." useradd $1 &> /dev/null echo "$1" | passwd --stdin $1 &> /dev/null echo echo "add user $1 is finishied." echo echo "user $1 UID is `id -u $1`." fi auid=`id -u $1` if [ $[$auid%2] -eq 0 ];then echo echo "$1 UID is even number." else echo "$1 UID is odd number." fi
通过命令行参数给定2个文本文件名,返回每个文件的行数,并说明其中行数较多的文件;
#!/bin/bash # if [ $# -lt 2 -o $# -gt 2 ];then echo echo "Just need two args." exit 22 echo "exit 22" fi if [ ! -f $1 -o ! -f $2 ];then echo echo "Need two files,not the other filesystem." exit 33 echo "exit 33." fi file1_line=`cat $1 | wc -l` echo "$1 file lines are $file1_line." file2_line=`cat $2 | wc -l` echo echo "$2 file lines are $file2_line." if [ $file1_line -ge $file2_line ];then echo echo "The lager file's line is $1." else echo echo "The lager file's line is $2." fi