Linux 脚本:
脚本一般为文本文件,运行脚本事实上是运行一个bash进程,此进程负责从脚本文件中读取一个执行逻辑,而后由bash进程负责解析并运行此逻辑;
启动脚本:
(1) # bash /PATH/TO/SCRIPT_FILE
(2) 一个执行权限,
# ./PATH/TO/SCRIPT_FILE
[root@iZ28qzns9m4Z ~]# vi date.sh [root@iZ28qzns9m4Z ~]# sh date.sh #第一种执行方法 Thu, 17 Sep 2015 12:43:37 +0800 [root@iZ28qzns9m4Z ~]# ll total 4 -rw-r--r-- 1 root root 22 Sep 17 12:43 date.sh [root@iZ28qzns9m4Z ~]# chmod +x date.sh #第二种执行方法 [root@iZ28qzns9m4Z ~]# ll total 4 -rwxr-xr-x 1 root root 22 Sep 17 12:43 date.sh [root@iZ28qzns9m4Z ~]# ./date.sh Thu, 17 Sep 2015 12:44:05 +0800 [root@iZ28qzns9m4Z ~]#
bash脚本的常用选项:
-n: 检查脚本中的语法错误;
-x:调试执行脚本;
命令状态结果:
bash进程用于追踪执行的命令成功与否的状态:
0: 成功
1-255:失败
[root@iZ28qzns9m4Z ~]# vim date.sh [root@iZ28qzns9m4Z ~]# sh -n date.sh [root@iZ28qzns9m4Z ~]# sh -x date.sh + date -s date: option requires an argument -- 's' Try 'date --help' for more information. [root@iZ28qzns9m4Z ~]# vi date.sh [root@iZ28qzns9m4Z ~]# sh -n date.sh [root@iZ28qzns9m4Z ~]# sh -x date.sh + date -R Thu, 17 Sep 2015 14:36:06 +0800 [root@iZ28qzns9m4Z ~]# echo $? 0 [root@iZ28qzns9m4Z ~]# vi date.sh [root@iZ28qzns9m4Z ~]# echo $? 0 [root@iZ28qzns9m4Z ~]# sh date.sh date: option requires an argument -- 's' Try 'date --help' for more information. [root@iZ28qzns9m4Z ~]# echo $? 1 [root@iZ28qzns9m4Z ~]#
自定义脚本的状态结果:
exit n
[root@localhost bashtest]# vim t1.sh [root@localhost bashtest]# sh -x t1.sh + useradd test001 useradd: user 'test001' already exists + echo test001 + passwd --stdin test001 Changing password for user test001. passwd: all authentication tokens updated successfully. + exit 9 [root@localhost bashtest]# echo $? 9 [root@localhost bashtest]#
注意:脚本中任何位置执行了exit命令即会终止当前shell进程;
条件测试:test
界定程序执行环境;
(1) 根据运行的命令的状态结果;
(2) 测试表达式
test 命令
[空格 命令 空格 ]
[[空格 命令 空格]]
[root@iZ28qzns9m4Z ~]# test -e /test [root@iZ28qzns9m4Z ~]# echo $? 1 [root@iZ28qzns9m4Z ~]# [ -e /test ] [root@iZ28qzns9m4Z ~]# echo $? 1 [root@iZ28qzns9m4Z ~]# [root@iZ28qzns9m4Z ~]# [[ -e /var ]] [root@iZ28qzns9m4Z ~]# echo $? 0 [root@iZ28qzns9m4Z ~]#
整数测试:隐含着做数值大小比较,所以不要给变量引用加引用;
$A -gt $B:是否大于;是则为“真”,否则为“假”;
$A -ge $B: 是否大于等于;
$A -lt $B:是否小于;
$A -le $B: 是否小于等于;
$A -eq $B: 是否等于;
$A -ne $B:是否不等于;
[root@iZ28qzns9m4Z ~]# a=9 [root@iZ28qzns9m4Z ~]# b=12 [root@iZ28qzns9m4Z ~]# [[ $a -gt $b ]] [root@iZ28qzns9m4Z ~]# echo $? 1 [root@iZ28qzns9m4Z ~]# [[ $a -ge $b ]] [root@iZ28qzns9m4Z ~]# echo $? 1 [root@iZ28qzns9m4Z ~]# [[ $a -lt $b ]] [root@iZ28qzns9m4Z ~]# echo $? 0 [root@iZ28qzns9m4Z ~]# [[ $a -le $b ]] [root@iZ28qzns9m4Z ~]# echo $? 0 [root@iZ28qzns9m4Z ~]# [[ $a -eq $b ]] [root@iZ28qzns9m4Z ~]# echo $? 1 [root@iZ28qzns9m4Z ~]# [[ $a -ne $b ]] [root@iZ28qzns9m4Z ~]# echo $? 0 [root@iZ28qzns9m4Z ~]#
字符串测试:
"$A" > "$B":是否大于;
"$A" < "$B":是否小于;
"$A" == "$B":是否等于;
"$A" != "$B":是否不等于;
-z "$A":是否为空;空则为“真”,否则为“假”
-n "$A":是否不空;不空则“真”,空则为“假”
[root@iZ28qzns9m4Z ~]# a=glancesli #103 108 97 110 99 101 115 108 105 [root@iZ28qzns9m4Z ~]# b=nancy #110 97 110 99 121 [root@iZ28qzns9m4Z ~]# test "$a" = "$b" && echo Ture||echo false false [root@iZ28qzns9m4Z ~]# [ "$a" == "$b" ] && echo Ture || echo false false [root@iZ28qzns9m4Z ~]# [ "$a" != "$b" ] && echo Ture || echo false Ture [root@iZ28qzns9m4Z ~]# [ -z "$a" ] && echo Ture || echo false false [root@iZ28qzns9m4Z ~]# [ -n "$a" ] && echo Ture || echo false Ture [root@iZ28qzns9m4Z ~]# test "$a" \> "$b" && echo ture||echo false false [root@iZ28qzns9m4Z ~]# test "$a" \< "$b" && echo ture||echo false ture [root@iZ28qzns9m4Z ~]# [[ "$a" < "$b" ]] && echo Ture || echo false Ture [root@iZ28qzns9m4Z ~]# [[ "$a" > "$b" ]] && echo Ture || echo false false [root@iZ28qzns9m4Z ~]#
注:字符串比较大于小于号必须转义,即加反斜线。字符串比较的顺序是按ASCII表的顺序的,大写字母比小写字母的值小。
文件测试:测试文件的存在性以及属性;
-e $file: 是否存在;存在则为“真”,否则为“假”;
-a $file: 同上;
-f $file:文件是否存在且为普通文件;
-d $file:文件是否存在且为目录;
-h $file:是否存在且为符号链接文件;
-L $file: 同上
-b $file:是否存在且为块设备文件;
-c $file:是否存在且为字符设备文件;
-S $file:是否存在且为套接字文件;
-p $file: 是否存在且为管道文件;
-r $file: 当前用户对文件是否拥有读权限;
-w $file:当前用户对文件是否拥有写权限;
-x $file:当前用户对文件是否拥有执行权限;
-u $file:文件是否拥有SUID权限;
-g $file:文件是否拥有SGID权限;
-k $file:文件是否拥有sticky权限;
-O $file: 当前用户是否为指定文件的属主;
-G $file: 当前用户是否为指定文件的属组;
[root@iZ28qzns9m4Z home]# mkdir abc [root@iZ28qzns9m4Z home]# ll total 12 drwxr-xr-x 2 root root 4096 Sep 17 17:13 abc drwxr-xr-x 2 root root 4096 Sep 17 17:01 bashtest drwx------ 2 user001 user001 4096 Sep 17 15:13 user001 [root@iZ28qzns9m4Z home]# test -e abc [root@iZ28qzns9m4Z home]# test -e abc && echo true || echo false true [root@iZ28qzns9m4Z home]# test -e bcd && echo true || echo false false [root@iZ28qzns9m4Z home]# test -a bcd && echo true || echo false false [root@iZ28qzns9m4Z home]# test -a abc && echo true || echo false true [root@iZ28qzns9m4Z home]# test -f abc && echo true || echo false false [root@iZ28qzns9m4Z home]# test -d abc && echo true || echo false true [root@iZ28qzns9m4Z home]# ln -s abc/ cde [root@iZ28qzns9m4Z home]# ll total 12 drwxr-xr-x 2 root root 4096 Sep 17 17:13 abc drwxr-xr-x 2 root root 4096 Sep 17 17:01 bashtest lrwxrwxrwx 1 root root 4 Sep 17 17:15 cde -> abc/ drwx------ 2 user001 user001 4096 Sep 17 15:13 user001 [root@iZ28qzns9m4Z home]# test -h abc && echo true || echo false false [root@iZ28qzns9m4Z etc]# test -L system-release && echo true || echo false true [root@iZ28qzns9m4Z etc]# test -h system-release && echo true || echo false true [root@iZ28qzns9m4Z home]# test -b abc && echo true || echo false false [root@iZ28qzns9m4Z home]# test -c abc && echo true || echo false false [root@iZ28qzns9m4Z home]# test -r abc && echo true || echo false true [root@iZ28qzns9m4Z home]# vim te1.sh [root@iZ28qzns9m4Z home]# test -rxw abc && echo true || echo false -bash: test: -rxw: unary operator expected false [root@iZ28qzns9m4Z home]# test -w abc && echo true || echo false true [root@iZ28qzns9m4Z home]# test -x abc && echo true || echo false true [root@iZ28qzns9m4Z home]# test -u abc && echo true || echo false false [root@iZ28qzns9m4Z home]# test -O abc && echo true || echo false true [root@iZ28qzns9m4Z home]# test -G abc && echo true || echo false true
双目操作符:
$file1 -nt $file2: file1是否新于file2, file1的最近一次的修改时间戳是否晚于file2的;
$file1 -ot $file2: file1是否旧于file2, file1的最近一次的修改时间戳是否早于file2的;
$file1 -ef $file2:file1与file2是否指向了同一个inode;测试二者是否为同一个文件的硬链接;
[root@iZ28qzns9m4Z bashtest]# ll total 8 -rwxr-xr-x 1 root root 140 Sep 17 15:42 1.sh -rw-r--r-- 1 root root 74 Sep 17 15:43 2.sh -rw-r--r-- 1 root root 0 Sep 17 17:01 nancy [root@iZ28qzns9m4Z bashtest]# test 2.sh \-ot 1.sh && echo true || echo false false [root@iZ28qzns9m4Z bashtest]# test 2.sh \-nt 1.sh && echo true || echo false true [root@iZ28qzns9m4Z bashtest]# test 2.sh \-ef 1.sh && echo true || echo false false [root@iZ28qzns9m4Z bashtest]# [root@iZ28qzns9m4Z bashtest]# ln -s nancy n1.sh [root@iZ28qzns9m4Z bashtest]# ln -s nancy n2.sh [root@iZ28qzns9m4Z bashtest]# test n2.sh \-ef n1.sh && echo true || echo false true [root@iZ28qzns9m4Z bashtest]#
测试表达式:
整数测试:-gt, -lt, -ge, -le, -eq, -ne
字符串测试:==, >, <, !=, -z, -n, =~
注意:
(1) 字符串等会比较测试:[ "$hostname" == 'localhost' ]
(2) 模式匹配测试:[[ "STRING" =~ PATTERN ]]
组合测试条件:
条件间逻辑运算:
与:多个条件要同时满足;
或:多个条件满足其一即可;
非:对指定的条件取反;
表达式组合:
与:[[ CONDITION1 -a CONDITION2 ]]
或:[[ CONDITION1 -o CONDITION2 ]]
非:[ ! CONDITION ]
命令组合:
与:COMMAND1 && COMMAND2 <-- [ EXPR1 ] && [ EXPR2 ]
或:COMMAND1 || COMMAND2
非:! COMMAND
短路操作符:&& 与
false && true = false
false && false = false
true && false = true
true && true = true
if COMMAND1; then
COMMAND2
fi
短路操作符:|| 或
true || true = true
true || false = true
false || true = true
false || false = false
if ! COMMAND1; then
COMMAND2
fi
COMMAND1 && COMMAND2 || COMMAND3
if COMMAND1; then
COMMAND2
else
COMMAND3
fi