1、顺序结构体
命令从上往下顺序执行
2、分支结构体
1)判断真假
test 表达式 或者 [ 表达式 ](必须有空格) 真返回0,假返回1 test的别名是[, 参数是]
判断表达式 | 记忆 | 解释 |
!表达式 | | |
表达式1 -a 表达式2 | and | 相与 |
表达式2 -o 表达式2 | or | |
-z string | zero | string为空字符串,则返回真0 |
-n string | not zero | |
string1 = string2 | | 两个字符窗相等,返回0 |
string1 != string2 | | |
INTEGER1 -eq INTEGER2 | equal | |
INTEGER1 -ge INTEGER2 | greater equal | 大于等于 |
INTEGER1 -gt INTEGER2 | greater | 大于 |
INTEGER1 -le INTEGER2 | little equal | 小于等于 |
INTEGER1 -lt INTEGER2 | little | 小于 |
INTEGER1 -ne INTEGER2 | not equal | 不等 |
文件存在?文件类型? | ||
-d FILE | dir | 如果FILE是目录则为真 |
-e FILE 同-a | exists | 是否存在如果是文件则为真 |
-N | | 检测文件自从上次读取之后是否被修改 |
-f | | 是否是文件,是否是常规文件 |
-s | | 文件存在且不为空 |
-b、-c、-L、S、p | | 块文件、字符文件、符号连接 套接字、命名(FIFO)管道 |
硬连接实际是文件本身 | | |
rwx | ||
-r、-w、-x | read | 存在且可读、、 |
-g、-u | sgid、suid | 以文件所有用户/组的身份运行 |
属主、属组 | ||
-O、-G | | 是否属于当前用户或组 |
-ef 比较两个文件是否为同一文件系统中相同inode节点的硬连接,
比较文件是否相同用diff -q $file1 $file2,相同返回码0
if [ new -nt old ]; then比较修改时间mtime n——new t——time o——old -ot/-nt 不能对访问时间atime inode修改时间ctime进行测试
字符串比较测试
[ = ] [ != ] [[ > ]] [[ < ]]
-z 空字符串;最好用“”把变量引起来,因为当为空时没引号会是这样 [ -z ]不合法
-n 非空字符串;
正则表达式测试
#!/bin/bash
for rpms in /home/lixn/Downloads/*
do
rpmname=`basename $rpms`
if [[ $rpmname =~ .*\.rpm ]];then
echo "$rpmname is a .rpm package"
else
echo "File \"$rpmname\" is not a .rpm name"
fi
done
也有类似python正则的(),
if [[ $rpmname =~ (.+)_(.*)_(.*)\.rpm ]]; then
echo “package ${BASH_REMATCH[1]}第一个括弧
bash正则表达式
数值测试 -eq -ne -lt -gt -le -ge
组合测试 &&——逻辑与 if [ -r "$filename" ] && [ -s "$filename" ]; then md5sum $filename 前边不成立后边就不进行了(短路)
||——逻辑或
bash - filename=${1:-/etc/hosts} 和 filename=/etc/hosts 的区别
例如:
[lixn@localhost ~]$ [-d learn] && cd learn
bash: [-d: command not found...
[lixn@localhost ~]$ [ -d learn ] && cd learn
[lixn@localhost learn]$
2)if分支语句
if list; then list; [elif list; then list]...[else list] fi;then后可以没有换行符,换行可以用;代替
#!/bin/bash
if [ `id -u` -eq 0 ]; then
PS1='##'
else
PS1='$$'
fi
3) case分支语句,可以使用模式匹配
#!/bin/bash
case $1 in
[0-9]) echo 'digital';;
[a-z]) echo 'lower char';;
[A-Z]) echo 'upper char';;
"Good") echo 'OK';;
*) cd /tmp
touch a
echo "Other";;
esac
;;——表示不再执行其他语句
;;&——表示还要匹配接下来的所有模式
;&——表示接下来的模式已经匹配
3、循环语句
1)for循环语句
for name [ [ in [ word ... ] ] ; ] do list; done
for (( expr1; expr2; expr3 )) ; do list; done
#!/bin/bash
for i in 1 2 3 4 5 6
do
echo -n "$i次|"
done
cd /tmp
for fil in * ; do
[ -f ${fil} ] && mv ${fil} ${fil}.old
[ -d ${fil} ] && break
done
total=1
for ((i=1; i<10; i=i+1))
do
[ `expr $i % 2` -eq 0 ] && continue
total=`expr ${total} \* $i`
done
echo ${total}
2)while循环
while list; do list; done
#!/bin/bash
#通过管道循环读取/etc/passwd内容
cat /etc/passwd | while read line
do
#以:为分割符,只读取第一个字段
user=`awk -F : '{print $1}' <<< ${line}`
echo "Account: ${user}"
done
3) select选择语句
1 PS3="Please Select:"
2 menus="com|net|org|edu|quit"
3 IFS="|"
4 a='Apply '
5 b=' domain'
6 select item in $menus
7 do
8 case $item in
9 com) echo "$a$item$b";;
10 net) echo "$a$item$b";;
11 org) echo "$a$item$b";;
12 edm) echo "$a$item$b";;
13 quit) break;;
14 esac
15 done
4)break continue 循环控制
1 for fil in *
2 do
3 if [ $fil = "." -o $fil = ".." ]
4 then
5 echo 'x'
6 continue
7 fi
8 echo $fil
9 [ $fil = '123' ] && break
10 cp -r $fil $fil.old
11 done
内容大部分引用王良明、赖国明著作,敬谢!
bash - filename=${1:-/etc/hosts} 和 filename=/etc/hosts 的区别