SHELL学习笔记2

来源:互联网 发布:觉得自己很透明知乎 编辑:程序博客网 时间:2024/06/06 21:01

三种计算字串的长度的方法

1.echo {#char}
2.echo ${char} | wc -c
3.echo $(expr length "$char")

1.程序执行效率问题

1.time for i in $(seq 11111);do count=${#chars};done;
real    0m0.743s
user    0m0.727s
sys     0m0.007s

2.time for i in $(seq 11111);do count=`echo ${char} | wc -c`;done;
real    0m28.207s
user    0m6.423s
sys     0m21.683s

3.time for i in $(seq 11111);do count=`echo $(expr length "$chars")`;done;
real    0m28.004s
user    0m6.218s
sys     0m21.150s
综上所述我们得出以下结论:
我们通过time + 要执行的命令发现运用bash内置的命令进行执行操作时效率最高。
因此我们最好把man bash里面的变量处理知识点看一下。

2.双括号(())运算的事例

请试下一个加、减、乘、除等功能的计算器。通过命令行传参的方式
vim cal.sh
#!/bin/bash
echo $(($1$2$3))
然后我们通过sh ./cal.sh 4+2就可以进行计算。 #既通过把后面的表达式传递到前面的脚本中执行,就是简单的把3个参数排在一起就OK了。

3.Let变量的数值运算

i=2
let i=i+8
echo $i
10
此时当我们把let去掉后:i=i+8
echo $i
i+8
提示:let i=i+8等同于((i=i+8)),但是后者的效率更高。

4.变量的数值运算与特殊应用expr命令

expr命令一般用于整数值,但也可用于字符串,用来求表达式变量的值,同时expr也是一个手工命令行计算器。
我们之前用过expr来计算字符串的长度:echo $(expr length `UESTC`)
1>或者用于计算:
expr 2 + 2
expr 2 \* 2
注意这里运算符左右都有空格。
2>expr在循环中可以用于增量计算。首先循环初始化为0,然后循环值加1,反引号的用法为命令替换。最基本的一种是从(expr)命令接受输入并将之放入循环变量。
例:给自变量i加1
i=0
i=`expr $i + 1`        //效率低
echo $i
1
3>expr $[$a+$b]表达式形式,其中$a$b可为整数值
expr $[2+3]
5
这种书写形式符号两边不需要加空格。expr将其后的串解释为表达式并计算其值,运算符前后需要有空格。
4>其他特殊用法:此时我们注意到ssh-copy-id脚本
if expr "$1" : ".*\.pub" ; then                  #匹配*.pub格式的文件如果是则为真。例如:
expr "uestc.pub" : ".*\.pub"
9                                                               #返回非0值为真,如果返回值为0则为假。我们注意到这个非0值其实是返回前面的字符个数。
5>为了更方便阅读我们在结尾再加上两个语句:expr "uestc.pub" : ".*\.pub" && echo Match || echo Not-Match
通过expr判断变量是否为整数。
#!/bin/bash
while do
read -p "Please input an interger: " a                #-t 5这个参数表示5秒后不输入就超时退出
expr $a + 0 >&/dev/null
[ $? -eq 0 ] && echo init || echo chars
done
6>通过expr计算字符串的长度
expr length "$UESTC"

4.变量的数值计算

bc计算器的用法
1>echo 3+4 | bc                 #通过管道交给bc
7
2>另外还有个例子:我们要计算1+2+3+...+10可以也可以通过管道接bc
seq -s "+" 10 | bc
55
3>保留小数点问题:scale=n
echo "scale=2; 5.31/2.14" | bc
4>进制转换 obase=n
echo "obase=2; 8" | bc        #这里是将十进制的8转化为二进制。
5>typeset命令也可以进行运算,下面去个例子
typeset -i A=1 B=3
A=A+B
echo $A不过这种方式很少见
6>$[]这个前面个expr又结合使用
echo $[2 + 3]
不过还是推荐$(())这样的用法比较好。
终极作业:打印杨辉三角

5.Shell内置变量read的用法

最常用的-p prompt:设置提示信息
-t timeout 设置输入等待的时间,单位默认为秒。
例如:
read -t 10 -p "Pls input two number: " a b   #10s后退出
还有另一种方法:
each -n "Pls input two  number: "
read a b
但是如果read读入的不是数字怎么办呢?
实例:
#!/bin/bash
while true
do
  read -p "Pls input two num: " a b
  expr $a + 0 >&/dev/null
  [ $? -ne 0 ] && continue
  expr $b + 0 >&/dev/null
  [ $? -ne 0 ] && continue || break
done
echo "a-b=$(($a-$b))"
将上面改为命令行传参的方式并优化
#!/bin/bash
a="$1"
b="$2"
Usage(){
      echo "USAGE:sh $0 num1 num2"
      exit 1
}

if [ $# -ne 2 ]; then
   Usage
fi

expr $1 + 0 >&/dev/null
[ $? -eq 0 ] && Usage
expr $2 + 0 >&/dev/null
[ $? -nq 0 ] && Usage

echo "a+b=$(($a+$b))"

6.条件测试的多种方式

在bash的各种流程控制结构中通常要进行各种测试,然后根据测试结果执行不同的操作,有时也会通过与if等条件语句相结合,使我们可以方便的完成判断。
与现实生活中比如你想找一个人出去约,你会先事先打电话确认其是否有时间。
格式1:test<测试表达式>
格式2:[<测试表达式>]
格式3:[[<测试表达式>]]
说明:
格式1和格式2是等价的。
格式3为扩展的test命令。
提示:
在[[]]中可以使用通配符进行模式匹配。&&、||、>、>等操作符可以应用于[[]]中,但是不能应用与[]中。对整数进行关系运算,也可以使用shell的算术运算符(()) //注意||符号两边最好不要有空格。
格式一:实例1:
test -f file && echo true||echo false               #test -f file这句话的意思是判断file是不是文件或者说这个文件存不存在。
false
touch file
test -f file && echo true||echo false
true
实例2:
test ! -f file && echo true||echo false
true
touch file
test ! -f file && echo true||echo false
false
格式二:实例:
[ -f file ] && echo true||echo false
[ ! -f file ] && echo true||echo false
[ -f file ] && cat file     #即使这个文件不存在,但是也不会报错,如果我们直接cat 空文件,此时会提示没有文件
格式三:实例:
[[ -f file && -d folder ]] && echo true||echo false              #这种情况下单中括号却不可以不过可以使用-a(and) 代替 &&;-o(or)代替||

下面是一些常用的文件测试操作符号:
-f  文件存在
-d 目录存在
-s 文件存在且非空
-e 文件存在即为真
-r 文件存在且可读                  #记住这些权限对于root用户无效,结果始终返回正确
-w 文件存在且可写
-x 文件存在且可执行
-L 文件存在且为链接
f1 -nt f2 文件1比文件2更新
f1 -ot f2 文件1比文件2久
我们可以通过查看/etc/init.d/nfs这个脚本来学习这些文件操作符的使用.

7.字符串测试操作符

作用:比较两个字符串是否相同,字符串长度是否为l零,是否为null
-z "字符串"            #若串长度为0则真,-z可以理解为zero
-n "字符串"           #若串的长度不为0则为真。
"串1"="串2"          #相等为真  #也可以用符号==也可以
"串1"!="串2"          #不相等为真
注意:以上字符串测试操作符号一定要用""引起来!!!!

8.整数二元比较操作符



实例:
[ 2 > 1 ] && echo OK||echo False
OK
[ 2 < 1 ] $$ echo OK||echo False
OK
为什么呢?我们必须注意当使用单中括号时必须使用转义字符:
[ 2 \< 1 ] && echo OK||echo False
False
所以说单括号我们最好不要用符号表示法
[ 2 -ge 3 ] && echo OK||echo False
但是经过测试=和!=则不需要转义!
同样我们也可以比较字符的长度,注意字符或字符串必须用双引号引起来

9.逻辑操作符



10.例子

1>[ -f "$UESTC" ] && echo 1||echo 0                    #这是条件表达式的用法:返回1为真0位假,这点与状态变量($?)不同。
2>
file1=/etc/services ; file2=/etc/rc.local
echo $file1 $file2
[ -f "file1" ] && echo 1||echo 0

11.多文件单中括号[]与或非测试

对于单中括号推荐使用-a 或 -o,不过也可以用&& 或 ||不过此时需要把&&或||放在中括号外面 例如:
[ -f "$file1" ] && [ -f "$file2" ] $$ echo 1||echo 0
对于双中括号必须使用&& 或 ||。
一般系统脚本中会用到大量的判断语句
[ -r /etc/sysconfig/network ] && . /etc/sysconfig/network

学生学习问答案例:判断条件后面执行多条命令语句,也就是这种句式:[ 判断 ] || ( 命令1 命令2 命令3 )
这个命令其实我们前面讲过了,比如这条命令:cd $LOG_DIR||{ echo "Cannot change to necessary directory." >&2 exit 1 } 
对于上面的那个例子我们可以这样写:
[ 3 -ne 3 ] || {
      echo "I am a UESTC student"
      echo "I am a good man"
      exit 1
}
如果要写在一行中,每个命令还需要用分号结尾。
脚本中编写:[ 3 -ne 3 ] || { echo "I am a UESTC student" ; echo "I am a good man" ; exit 1 ; }
命令行中我们可以用:[ 3 -ne 3 ] || (echo "1"; echo "2")
还有一个例子:[ $ERROR -eq 0 ] && echo "jdk安装成功" || (echo "jdk安装失败,请检查!" && exit 1)
字符串测试举例:-n 串长度不为零则为真;-z串的长度为零则为零
我们在系统脚本nfs中找到相关的应用:
[ -n "$RPCNFSDARGS" -a "$NFSD_MODULE" !="noload" ] && { 
    [ -x /sbin/modprobe ] && /sbin/modprobe nfsd
}
其中空格的使用有两个注意:符号两边需要有空格,中括号内需要有空格
字符串测试bind系统启动脚本举例:named
if [ -n "$ROOTDIR" ]; then
   ROOTDIR=`echo $ROOTDIR | sed 's#//*#/#g; s#/$##'` ;
   rdl=`/usr/bin/readlink $ROOTDIR`;
   if [ -n "$rdl" ]; then
      ROOTDIR="rdl";
   fi
fi
整数条件测试举例
a1=10;a2=13
[ $a1 -eq $a2 ] && echo 1 || echo 0                #注意这里$a1 $a2虽然是数字,但是我们也可以把其当做字符串来处理。
0
另外还可以+、-、*、/等都可以用这这里,如果使用单中括号的话我们要注意使用转移字符。如果是双括号(包含双中括号和)
我们这里再来总结一下test的用法:
test -z "file1" && echo 1||echo 0 如果不加后面的我们根本不知道前面test命令是否执行成功,但是我们可以根据其后面的语句的返回值来判断其是否成功执行了前面的语句。
注意其逻辑哦:注意与test ! -z "file1" $$ echo 1||echo 0的逻辑刚好相反,这个作用与test -n "file1" $$ echo 1||echo 0相同

12.利用Shell制作单级及多级菜单

 显示单行信息我们用echo,显示多行信息我们用cat
#!/bin/bash
cat <<END
         1.[INSTALL LAMP]
         2.[INSTALL LANP]
         3.[INSTALL NFS]
         4.[INSTALL RSYNC]
         Please input which you want to install:
END
read a
[ $a -eq 1 ] && {
cat <<END
          1.[INSTALL APACHE]
          2.[INSTALL MYSQL]
          3.[INSTALL PHP]
          4.[Back]
END
}
read "a1"
[ $a1 -eq 1 ] && {
echo "You want to install: Apache"
}
[ $a1 -eq 2 ] && {
echo "You want to install: MYSQL"
}
[ $a1 -eq 3 ] && {
echo "You want to install: PHP"
}
这样就实现了多级显示的功能。
0 0
原创粉丝点击