test指令补充
文件相关操作
判断两个文件是否具备相同的inode(是否是硬链接文件)
if [$f1 -ef $f2]
判断两个文件谁更新
FILE1 -nt FILE2
FILE1 is newer (modification date) than FILE2
判断两个文件谁更旧
FILE1 -ot FILE2
FILE1 is older than FILE2
判断文件存在,且是一个块设备文件
-b FILE
FILE exists and is block special
判断文件存在,且是一个字符设备文件
-c FILE
FILE exists and is character special
判断文件存在,且是一个目录
-d FILE
FILE exists and is a directory
判断文件存在
-e FILE
FILE exists
判断文件存在,且是一个普通文件
-f FILE
FILE exists and is a regular file
判断文件存在,且是一个链接文件
-h FILE
FILE exists and is a symbolic link (same as -L)
-L FILE
FILE exists and is a symbolic link (same as -h)
判断文件存在,且是一个管道文件
-p FILE
FILE exists and is a named pipe
判断文件存在,且是一个套接字文件
-S FILE
FILE exists and is a socket
判断文件存在,且不是空文件
-s FILE
FILE exists and has a size greater than zero
判断文件存在,且具备可读权限
-r FILE
FILE exists and read permission is granted
判断文件存在,且具备可写权限
-w FILE
FILE exists and write permission is granted
判断文件存在,且具备可执行权限
-x FILE
FILE exists and execute (or search) permission is granted
练习:
输入一个文件名,判断文件是否存在,
如果文件不存在,则提示不存在,创建该文件
如果文件存在,判断文件类型 bcdLspf,并输出文件类型
判断文件是否是目录,如果是目录,则打印目录下的所有.sh文件
判断普通文件,则判断是否具备可写权限,如果不具备可写权限,添加可读可写可执行权限
写入字符串 hello
case...in
case varName in
常量表达式1)
shell语句
;;
常量表达式2)
shell语句
;;
......
*)
shell语句n
;; //可以省略
esac
- varName:变量名,就是switch的表达式
- 常量表达式:是varName的所有值
格式:
hello)
'hello')
"hello")
常量表达式可以使用使用按位或链接
A|a)
常量表达式可以和通配符结合
通配符:*,?,[]
h*)
h?)
9[0-9]|100) //90-100
- ;;类似switch中break的含义,退出case,最后一个可以省略不写,其余不可省略
- *)执行除了以上常量表达式以外的情况
输入一个成绩,使用case...in实现等级判断
90-100 A 70-89 B 60-69 C 0-59 D
输入一个表达式,使用case...in实现+-*/%
shell的循环结构
shell的循环:for,while,select...in
while
格式:
while [表达式] //while test 表达式
do
循环体
done
表达式为真循环,表达式为假则退出循环
死循环:
while [1]
练习:
计算n的阶乘
输入一个数组,使用循环输出数组元素,并计算平均值
输入一个数字,计算各个位数字之和
输入一个字符串实现字符串的逆置
for
格式1:(类似c语言,不可以循环稀疏代码)
for ((表达式1;表达式2;表达式3))
do
循环体
done
练习:
定义数组并赋值,循环输出
定义数组,初始化为/home/ubuntu/中的文件及目录名,循环输出数组
格式2:(类python 万能)
for varName in 选项列表
do
循环体
done
varName:类似循环变量i
选项列表:默认使用空格隔开
默认是常量
for i in 1 2 3 4 5
循环数组元素
for i in $arr[*]
选项列表为有序序列
格式:$(seq 起始值 间值 终止值)
格式:`seq 起始值 间值 终止值`
选项列表为有序序列
格式:{1..10} //“.”只能由两个,且两端起始值和终止值为常数
练习:
输入一个数组,计算最大值
输入一个值,使用for判断是否是完美数(除本身外的约数和等于本身)、
使用for实正三角打印
select...in
加强终端与页面的交互性
格式:
select varName in 选项列表
do
shell语句
done
按照选项列表依次把指定的选项列表的结果赋值给循环变量varName,如果在#?后面输入选项列表以外的值,则赋值为空,如果不输入选项,回车则重新打印选项列表的菜单
循环跳转语句
break
break n
n=1 //可以省略,表示退出一层循环
n!=1 //不可以省略,表示退出n层循环
continue
continue n
n=1 //可以省略,表示退出一层的本次循环进入下次循环
n!=1 //不可以省略,表示退出n层的本次循环进入下次循环
练习
1定义数组,初始化为/home/ubuntu/中的文件及目录名,使用循环1计算文件个数,目录个数
#!/bin/bash
arr=($(ls /home/ubuntu))
len=${#arr[*]}
w=0
m=0
for (( i=0 ;i<len;i++))
do
echo ${arr[i]}
if [ -f ${arr[i]} ]
then
((w++))
elif [ -d ${arr[i]} ]
then
((m++))
fi
done
echo "文件有$w个" "目录有$m个"
输入用户名和密码(加密输入),实现密码的三次登录 默认用户名admin 密码1234 账户存款10000
如果登录失败,则提示
第1次登录失败,还有2次机会
第2次登录失败,还有1次机会
第3次登录失败,账户被锁定
如果登录成功,则显示银行页面
1.账户余额
2.取款
3.存款
如果选择1,则打印当前的余额
如果选择2,则输入取款金额,如果取款金额大于实际金额,则提示账户余额不足,请重新输入,如果账户余额小于等于实际金额,则提示取款成功,剩余金额
如果选择3,则输入存款金额,并提示 存款成功,余额的值
#!/bin/bash
#user=admin
#mi=1234
cun=10000
read -p "输入用户" user
read -p "输入密码" mi
count=1
i=1
for (( i=1;i<=3;i++))
do
if [ $user "=" "admin" -a $mi -eq "1234" ]
then
echo "登陆成功"
select j in "账户余额" "取款" "存款"
do
case $j in
"账户余额")
echo $cun
;;
"取款")
read -p "输入取款金额" a
if [ $a -gt $cun ]
then
echo "账户余额不足,请重新输入"
elif [ $a -le $cun ]
then
echo "取款成功"
((cun-=a))
echo $cun
fi
;;
"存款")
read -p "输入存款金额" b
echo "存款成功"
((cun+=b))
echo $cun
esac
done
break 1
elif [ $count -eq 1 ]
then
echo "第1次失败,还有2次机会"
((count++))
read -p "输入用户" user
read -p "输入密码" mi
elif [ $count -eq 2 ]
then
echo "第2次失败,还有1次机会"
((count++))
read -p "输入用户" user
read -p "输入密码" mi
elif [ $count -eq 3 ]
then
echo "第3次失败,账户被锁定"
break
fi
done
输入一个数组实现冒泡排序
#!/bin/bash
read -p "输入一个数组" -a arr
len=${#arr[*]}
for(( i=1;i<len;i++))
do
for((j=0;j<len-i;j++))
do
k=$((j+1))
if [ ${arr[j]} -gt ${arr[k]} ]
then
t=${arr[j]}
arr[j]=${arr[j+1]}
arr[j+1]=$t
fi
done
done
echo ${arr[*]}