4.7输入read
C语言中的输入
int a;
scanf("%d",&a);
C++中的输入
int a;
cin >> a;shell中的输入:
read var1 ---->从终端输入var1的值
read -p "提示信息" 变量 ----->在用户输入前输出提示信息
read -s 变量 ---->输入时不会回显
read -t 秒数 变量 ------>如果n秒内不输入就结束读取
read -n 个数 变量 ------>输入n个字符后就结束读取
思考:
read的4个参数能否结合使用?
read -sp "请输入一个变量" -t 4 -n 5 var
4.8命令置换符
作用:把指令的运行结果赋值给变量
法一 ``(反引号常用) ~不按shift就能打出反引号
法二 $()
练习:
1、输出/etc/passwd中,查找到的sys用户的行号,用变量保存行号,并输出。
var=grep -nw sys /etc/passwd |cut -d : -f 1
echo $var
五数组
shell支持稀疏数组
5.1定义
int arr[]={2,4,7};
int arr1[4]={0}; shell中数组
数组名=(初始值1 初始值2 初始值3 ·····)
#shell中的数组,使用()包含初始化列表
#shell中数组的每个元素的间隔是空格,不是逗号
数组名=([下标]=初始值1 [下标]=初始值2 [下标]=初始值3 ······)
5.2访问数组中的元素
数组中存储多个数据,下标仍然从0开始,还是通过下标访问
${数组名[下标]} ----->获取数组中元素的值
arr[0]=89 ------>给arr数组中下标为0的元素赋值
5.3获取数组中元素的个数
${arr[@]} ----->获取数组中的所有元素
${arr[*]} ----->获取数组中的所有元素${#arr[*]} ----->获取数组中所有元素的个数
${#arr[0]} ----->下标为0的元素包含的字符的个数
#!/bin/bash
arr=(1 5 7 10)
arr1=([0]=100 [5]=90 [9]=7)
echo ${arr[3]}
echo ${arr1[5]}
#echo ${arr1[3]} #是一个空值,arr1中没有下标为3的元素
echo ${#arr[*]}
echo ${#arr1[*]}
#echo ${arr[*]}
#echo ${arr[@]}#给arr1这个稀疏数组添加下标为2的元素
arr1[2]=200
echo ${arr1[2]}
#添加元素后检验数组中元素的个数
echo ${#arr1[*]}
思考:
1、shell中是否可以使用已有的数组,给新的数组赋值
2、如果输出echo ${#arr[0]} ---->输出的结果是什么 下标为0的元素有多少个字符
5.4使用已有的数组给新的数组赋值
拿到已有数组的所有元素,给新的数组
arr=(12 90 100)
#使用arr给arr1数组赋值
arr1=(${arr[*]}) ---->数组元素需要加()arr2=(h e l)
arr3=(${arr[*]}${arr2[*]}) ---->100和h是连在一起的元素,arr3中元素的个数5
arr3=(${arr[*]} ${arr2[*]}) ---->100和h是分开的两个元素,arr3中元素的个数6
练习:
1、使用数组求,外部参数的个数,不可以直接使用$#
#!/bin/bash
a=($*)
echo ${#a[*]}
2、使用数组,求家目录下文件的个数,包括隐藏文件
#!/bin/bash
arr=($(ls ~/ -a))
echo ${#arr[*]}
echo ${arr[*]}
六、shell中的算数运算
shell本身擅长执行指令,不擅长做运算,shell中的运算需要借助于指令
*(()) * $[] let expr
6.1使用(())进行算数运算
shell中支持幂运算 **
格式:((表达式1,表达式2,表达式3,······)),每一个语句都会运行,取最后一个语句的结果
(())常用于整形数据的运算
(())内使用变量的值,可以加$也可以不加$
(())内运算符两侧可以加空格,也可以不加空格
(())支持几乎所有C语言的语法
获取(())的运算结果,$(()),如果想把运算的结果赋值给变量:变量名=$(()),还可以((变量名=表达式))
练习:
1、终端输入3位的变量,输出两个变量相加的结果
#!/bin/bash
read -n 3 var1
echo ""
read -n 3 var2
echo $((var1 + $var2))
2、计算root用户的uid和ubuntu用户的gid相加的结果
#!/bin/bash
rid=`id -u root`
gid=`id -g ubuntu`
echo $((rid+gid))
6.2使用$[]进行算术运算
格式:变量名=$[表达式1,表达式2,表达式3,······],取最后一个表达式的结果
$[]运算时,变量可以加$也可以不加
运算符两侧可以加空格,也可以不加空格
仍然支持幂运算
#!/bin/bash
rid=`id -u root`
gid=`id -g ubuntu`
ret=$[gid**rid]
echo $ret
6.3使用let进行算数运算
let 变量名=表达式,let运算时变量名一定和let间要有空格
使用变量的值,可以加$可以不加$
运算符两侧不能有空格
let一定要放在指令最前面的位置
#!/bin/bash
rid=`id -u root`
gid=`id -g ubuntu`
ret=$[gid**rid]
echo $retlet ret1=$rid+gid
echo $ret1
练习:
1、终端输入两个变量,分别使用$[]和let计算相加的结果
read -p “请输入一个变量” var1
read -p “请输入一个变量” var2
echo $[var1+var2]
let ret=var1+var2
echo $ret
6.4expr运算 ----->是指令
格式:expr 表达式
使用变量时必须加$
运算符两侧一定要加空格
expr不支持幂运算,也不支持自增自减运算
expr在使用时,某些字符需要转义:\|,\.,\*·······,判断在字符是否需要转义,可以现在命令行敲出该指令
由于expr是一条指令,指令的结果需要使用命令置换符接收
expr指令会自动回显指令的运行结果到终端
expr支持的更多运算
ARG1 | ARG2 若ARG1 的值不为0,则返回ARG1,否则返回ARG2ARG1 & ARG2 若两边的值都不为0,则返回ARG1,否则返回 0ARG1 < ARG2 ARG1 小于ARG2 #<需要转义ARG1 <= ARG2 ARG1 小于或等于ARG2ARG1 = ARG2 ARG1 等于ARG2ARG1 != ARG2 ARG1 不等于ARG2ARG1 >= ARG2 ARG1 大于或等于ARG2 #>需要转义ARG1 > ARG2 ARG1 大于ARG2
#!/bin/bash
var1=100
var2=9
expr $var2 \& $var1
expr $var2 \> $var1
expr $var2 \< $var1
expr可以进行的字符串运算
expr match $str1 $str2返回str2在str1中完全匹配到的个数
expr substr STRING POS LENGTH截取子串,从string的第pos位开始,截取长度为length的子串,pos从1开始
expr index STRING CHARS返回字符在string中第一次出现的位置,如果跟了多个字符,返回最先的字符的位置
expr length STRING返回字符串的长度
#!/bin/bash
str1=hello
str2=hei
expr match $str1 $str2
expr substr $str1 2 3 #ell
expr index $str1 lehp #1,因为h在hello中最先出现
expr length $str1
练习:
1、求家目录下,第二个文件的,文件名长度(使用expr)
#!/bin/bash
arr=(`ls ~`) #先把家目录下的文件放在数组中
expr length ${arr[1]}#求数组中第二个而元素的长度
2、终端输入一个文件名,截取出文件的后缀(使用expr)
read var1
pos=`expr index $var1 "."`#从pos+1开始截取的原因是:不把.截取出来
expr substr $var1 $((pos+1)) 3
3、终端输入网址:www.hqyj.com,要求截取出网址的每个部分
www
hqyj
com 并且放在数组中
#!/bin/bash
read -p "请输入一个网址" net
pos=`expr index $net '.'`
arr[0]=`expr substr $net 1 $((pos-1))` #截取到www放入数组中
#求输入网址的长度
len=`expr length $net`
#截取出除www.外的其他部分
str2=`expr substr $net $((pos+1)) $len`#找剩余部分.出现的位置
pos2=`expr index $str2 '.'`#截取出网址里两个.中间的部分
arr[1]=`expr substr $str2 1 $((pos2-1))`#截取出最后剩余的部分
arr[2]=`expr substr $str2 $((pos2+1)) $len`echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}
七、shell中的分支结构
7.1if分支
C语言中的if
if(条件1)
{条件1成立执行的代码块;
}
else if(条件2)
{条件1不成立但是条件2成立执行的代码块;
}shell中的if
单分支if
if [ test表达式 ] -----> if test 表达式
thentest表达式成立执行的语句
fi双分支
if [ test表达式 ] -----> if test 表达式
thentest表达式成立执行的语句
elsetest表达式不成立执行的语句
fi 多分支if
if [ test表达式 ] -----> if test 表达式
thentest表达式成立执行的语句
elif [ test表达式 ]
thentest表达式不成立执行的语句
fi
[]和[[]]的区别
[]是所有解析器都通用的test指令
[[]]只支持部分shell解析器
[[]]]内可以正确识别字符串的范围
[]test本身,不能正确识别字符串的范围,需要给字符串加""
[[]]内可以i使用&&和||,但是[]只能使用test的参数
7.2test指令的使用
i)对于整数的操作
-eq:相等
-ge:大于等于
-gt:大于
-le:小于等于
-lt:小于
-ne:不等于
#!/bin/bash
var1=100
var2=100if [ $var1 -gt $var2 ]
then #then表示if语句的开始echo "var1>var2"
elif [ $var1 -eq $var2 ]
thenecho "var1==var2"
elseecho "var1<var2"
fi #fi表示if语句的结束
练习:
1、终端输入年份,判断闰平年,四年一闰,百年不闰,四百年再闰
#!/bin/bash
read -p "请输入年份" year#if [ $((year%4)) -eq 0 ] && [ $((year%100)) -ne 0 ] || [ $((year%400)) -eq 0 ]
#if [[ $((year%4)) -eq 0 && $((year%100)) -ne 0 || $((year%400)) -eq 0 ]]
if [ $((year%4)) -eq 0 -a $((year%100)) -ne 0 -o $((year%400)) -eq 0 ]
thenecho "${year}是闰年"
elseecho "${year}是平年"
fi
ii)test指令中的逻辑与和逻辑或
-a:和C中的逻辑与相同
-o:和C中的逻辑或相同
iii)test对于字符串的判断
-n STRING:判断字符串非空
-z STRING:判断字符串为空
STRING1 = STRING2:判断两个字符串相等
STRING1 != STRING2:判断两个字符串不相等
iv)test对文件的判断
FILE1 -nt FILE2:f1的时间戳比f2的更新
FILE1 -ot FILE2:f1的时间戳比f2的更旧
-e FILE:判断文件是否存在
-f FILE:文件存在是一个普通文件
-s FILE:文件存在且有内容
-S FILE:文件存在且为套接字文件
-L/-h FILE:文件存在且为软链接文件
-p FILE:文件存在且为管道文件
-b FILE:文件存在且为块设备文件
-c FILE:文件存在且为字符设备文件
-r FILE:文件存在有可读权限
-w FILE:文件存在有可写权限
-x FILE:文件存在有可执行权限
判断家目录下,普通文件的个数和目录文件的个数
#!/bin/bash
var=(`ls -la ~/`)
var1=(`ls -la ~/ | cut -d r -f 1 | grep -i d`)
var2=(`ls -la ~/ | cut -d r -f 1 | grep -i -`)
echo ${#var[*]}
echo ${#var1[*]}
echo ${#var2[*]}
输入一个文件名,判断是否为shell脚本文件,如果是脚本文件,判断是否有可执行权限,如果有可执行权限,运行文件,如果没有可执行权限,给文件添加可执行权限。
#!/bin/bash
read -p 请输入一个文件名 filename
length=`expr length ${filename}`
fileType=`expr substr ${filename} $((length-2)) 3`
echo ${length}
echo ${fileType}
authority=`getfacl ${filename}`
echo ${authority}
userAuth=`cut -d " " -f 10 ${authority}`
echo ${userAuth}
if [ $fileType == ".sh" ]
then echo "是shell脚本"#`bash ${filename}`
elseecho "不是shell脚本"
fi
终端输入两文件名,判断哪一个文件更新
#!/bin/bash
read -p 请输入文件名1 file1
read -p 请输入文件名2 file2
if [ file1 -nt file2 ]
thenecho "${file1} newer than ${file2}"
elseecho "${file1} older than ${file2}"
fi
写一个shell脚本,获取当前用户名,用户id和工作路径
#!/bin/bash
whoami
echo `whoami | id -u`
echo `pwd`