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" \
ture
[root@iZ28qzns9m4Z ~]# [[ "$a" 
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
字符串测试:==, >, 
注意:
(1) 字符串等会比较测试:[ "$hostname" == 'localhost'  ]
(2) 模式匹配测试:[[ "STRING" =~ PATTERN ]]
组合测试条件:
条件间逻辑运算:
与:多个条件要同时满足;
或:多个条件满足其一即可;
非:对指定的条件取反;
表达式组合:
与:` CONDITION1 -a CONDITION2 `
或:` CONDITION1 -o CONDITION2 `
非:[ ! CONDITION ]
命令组合:
与:COMMAND1 && COMMAND2  
或: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