shell中算术运算符和read

shell编程是linux运维必备技能-----------!!!!!很重要

学习之前先梳理理论知识很重要,扯一堆

编程基础

程序

   程序:算法+数据结构

   数据:是程序的核心

   数据结构:数据在计算机中的类型和组织方式

   算法:处理数据的方式

程序编程风格:

   过程式:以指令为中心,数据服务于指令;关注执行的过程

   对象式:以数据为中心,指令服务于数据;关注最终结果

shell程序:提供了编程能力,解释执行

计算机内部运行是通过二进制指令

编程语言是人与计算机交互的语言

低级编程语言:

       机器:二进制数字  0  1  ,与自然语言差异太大,难懂,晦涩

       汇编:用一些辅助记忆的符号代替机器指令

                 汇编语言写好的程序需要汇编程序转换成机器指令

                 汇编语言稍微好理解,比如通过 add  move等助记符号大大提高了易懂性能

高级汇编:

      编译:高级语言-->编译器-->机器代码-->执行

      解释 :高级语言-->执行-->解释器-->机器代码

     java 语言是通过源代码执行-->编译-->内部程序+Input-->Virtual machine 相当于内部机制-->Output

     所以java语言其实是进行两次编译

================================================================

编程的逻辑思维方式:

       顺序执行

       循环执行

       选择执行

shell编程:过程式+解释执行

        编程语言的基本结构:

           各种系统命令的组合

           数据存储:变量、数组

           表达式:a + b

           语句:if  

shell脚本:

包含一些命令或声明,并符合一定格式的文本文件

常用的shell类型有很多种 cat /etc/shells可以查看;主流用的还是 #!/bin/bash

shell脚本的用途有:

1.自动化常用命令

2.执行系统管理和故障排除

3.创建简单的应用程序

4.处理文本或文件

创建shell脚本的规则

  一、使用文本编辑器vim/vi 创建

     1.第一行必须包括shell声明序列:#!

           示例:#!/bin/bash

     2.添加注释

            注释以#开头

  第二步:运行脚本

      执行脚本的方法:

      1.

      /data/scripts/test.sh  加执行权限 chmod +x

      2.

      cd  /data/scripts/

      ./test.sh

      3.

      vim  /etc/profile.d/env.sh

      PATH=/data/scrpits/:$PATH

      test.sh

脚本调试:

    检测脚本中的语法错误

          bash  -n   /data/test.sh

    调试执行

          bash  -x   /data/test.sh

变量:

      变量:命名的内存空间

      变量:变量类型

          作用:

               1、数据存储方式

               2、参与的运算

3、表示的数据范围

类型:

字符

数值:整型、浮点型

#echo ${Name}12

ttyang12

pstree -p

(  )临时修改umask,并不会影响后续的umask值,()相当于开启一个子shell

[root@centos7 ~]#(umask 066;touch f3.txt)

[root@centos7 ~]#ll f3.txt

-rw------- 1 root root 0 Aug 13 22:57 f3.txt

[root@centos7 ~]#

[root@centos7 ~]#

[root@centos7 ~]#umask

0022

bash中变量的种类

      根据变量的生效范围等标准划分下面变量类型

              局部变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效

              环境变量:生效范围为当前shell进程及其子进程

              本地变量:生效范围为当前shell进程中某代码片断,通常指函数

              位置变量:$1, $2, ...来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数

              特殊变量:$?, $0, $*, $@, $#,$$      

     引入环境变量就是为了解决局部变量中子shell不能继承变量

局部变量

      1、变量赋值:name=‘value’

      2、可以使用引用value

             (1) 可以是直接字串:name=“root"

             (2) 变量引用:name="$USER"

             (3) 命令引用:name=`COMMAND`

                                   name=$(COMMAND)

     3、变量引用:${name} 或者 $name

            " " 弱引用,其中的变量引用会被替换为变量值

            ' ' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串

     4、显示已定义的所有变量:set

     5、删除变量:unset name

环境变量

     1、变量声明、赋值:

           export name=VALUE

           declare -x name=VALUE

     2、变量引用:

           $name, ${name}

     3、显示所有环境变量:

           env

           printenv

           export

           declare -x          

     4、删除变量:

            unset name

        bash中内嵌的环境变量

            PATH

         SHELL

         USER

         UID

         HOME

         PWD

         SHLVL

LANG

MAIL

HOSTNAME

HISTSIZE

_ 下划线

*************

{ } 不开启子进程  ()开启子进程             

****************************************

$0 脚本自身的变量

环境变量从上往下传,而不能从上往下传

只读和位置变量

    只读变量:只能声明,但不能修改和删除

    1、声明只读变量:

           readonly name

           declare -r name

    2、查看只读变量:

           readonly -p

    位置变量:在脚本代码中调用通过命令行传递给脚本的参数

         $1, $2, ... 对应第1、第2等参数,shift [n]换位置

         $0 命令本身

         $* 传递给脚本的所有参数,全部参数合为一个字符串

         $@ 传递给脚本的所有参数,每个参数为独立字符串

         $# 传递给脚本的参数的个数

         注意:$@ $* 只在被双引号包起来的时候才会有差异

         set -- 清空所有位置变量

退出状态

      进程使用退出状态来报告成功或失败

      0 代表成功,1-255代表失败

      $? 变量保存最近的命令退出状态

     例如:

       ping -c1 -W1 hostdown &> /dev/null

       echo $?

退出状态码

     $?  表示上一条shell脚本执行的状态码  0 为成功  1-255 失败,为255种错误;只能追踪上一条命令的执行状态

       bash自定义退出状态码      

       exit [n]:自定义退出状态码

       注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字

       注意:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

shell 只支持整数,不支持小数  

算数运算

     bash中的算术运算:help let

     +, -, *, /, %取模(取余), **(乘方),乘法符号有些场景中需要转义

     实现算术运算:

        (1) let var=算术表达式

        (2) var=$[算术表达式]

        (3) var=$((算术表达式))

        (4) var=$(expr arg1 arg2 arg3 ...)

        (5) declare –i var = 数值

        (6) echo ‘算术表达式’ | bc

     bash有内建的随机数生成器变量:$RANDOM(0-32767)

           示例:生成 0 - 49 之间随机数

               echo $[$RANDOM%50]  

赋值

     增强型赋值:

         +=, -=, *=, /=, %=

     let varOPERvalue

         例如:let count+=3   自加3后自赋值

     自增,自减:

         let var+=1

         let var++

         let var-=1

         let var--

与运算:

  全1为1,只要有一个是0,结果就为0    相对门槛较高

或运算:

  有1为1,全0为0      相对门槛较低

与或:

  相同为假,不同为真

   规律:

    A^B=C

    C^B=A

短路与

cmd1 && cmd2 ; 如果cmd1 结果为失败,不执行第二个命令,如果cmd1 成功,执行第二个命令

短路或

cmd1 || cmd2:如果cmd1执行成功,不执行cmd2,如果cmd1失败,执行cmd2

test 本身就是 比较,是内部命令 ,详细参考-- help test

[root@centos7 ~]#x=hello

[root@centos7 ~]#y=ok

[root@centos7 ~]#test $x= $y

[root@centos7 ~]#test $x = $y && echo equal || echo not equal

not equal

bash的数值测试

   -v VAR

        变量VAR是否设置

   数值测试:

       -gt 是否大于

       -ge 是否大于等于

       -eq 是否等于

       -ne 是否不等于

       -lt 是否小于

       -le 是否小于等于

[root@centos7 ~]#n=20

[root@centos7 ~]#m=23

[root@centos7 ~]#test $m -gt $n    gt大于   

[root@centos7 ~]#echo $?

0

[root@centos7 ~]#test $m -lt $n      lt 小于

[root@centos7 ~]#echo $?

1

[ ]也可以作为逻辑判断,只要里面含有东西,就不为空,0 也表示不为空,且中括号前后都必须有空格

[root@centos7 ~]#NAME=ttyang; [ ] && echo true

[root@centos7 ~]#NAME=ttyang; ["" ] && echo true

[root@centos7 ~]#NAME=ttyang; [ "" ] && echo true

[root@centos7 ~]#NAME=ttyang; [ " " ] && echo true

true

[root@centos7 ~]#NAME=ttyang; [ 0  ] && echo true

true

[root@centos7 ~]#NAME=ttyang; [ "$VAR" ] && echo true

如果文件存在不创建,不存在就创建

[root@centos7 ~]#FILE=/data/test.txt; [ -a "$FILE" ] || touch $FILE

[root@centos7 ~]#ls /data

f1.txt  f2.txt  f3.txt  f4.txt  scripts  test.txt

容易出错的地方,举个例子;

删除环境变量,FILE已经制为空,但输出却是exist ,原因是它把$FILE作为整体当作判断是否为空,需要添加“”

[root@centos7 ~]#unset FILE;[ -e $FILE ] && echo $FILE is exist

is exist

[root@centos7 ~]#unset FILE;[ -e "$FILE" ] && echo $FILE is exist

[root@centos7 ~]#echo $?

1

x为变量,没有定义,无法比较;gt为判断前者是否大于后者,相当于下面第二个操作,所以也得加“”

[root@centos7 ~]#[ $x -gt 10 ]

-bash: [: -gt: unary operator expected

[root@centos7 ~]#[  -gt 10 ]

-bash: [: -gt: unary operator expected

[root@centos7 ~]#[ "$x"  -gt 10 ]

-bash: [: : integer expression expected

[[ ]]  用于正则表达式

bash的字符串测试

      字符串测试:

           = 是否等于

           > ascii码是否大于ascii码

           < 是否小于

           != 是否不等于

           =~ 左侧字符串是否能够被右侧的PATTERN所匹配   #注意: 此表达式一般用于[[ ]]中;扩展的正则表达式

           -z "STRING“ 字符串是否为空,空为真,不空为假

          -n "STRING“ 字符串是否不空,不空为真,空为假

   注意:用于字符串比较时的用到的操作数都应该使用引号

~ 指的是包含的意思

需要注意的是 =~ 必须连着写 ~ \ 分开写,否则会报语法错误

[root@centos7 ~]#str=goodee;[[ $str =~ o{2,} ]] && echo true

true

[root@centos7 ~]#n=234;[[ $n =~ o{2,} ]] && echo true

[root@centos7 ~]#n=234;[[ $n =~ [[:digit:]]+ ]] && echo true

true

[root@centos7 ~]#n=234;[[ $n =~ ^[[:digit:]]+$ ]] && echo true

true

同上面所讲的一致,为了避免变量为空报语法错误,需加“”

[root@centos7 ~]#unset n;[[ $n =~ ^[[:digit:]]+$ ]] && echo true

[root@centos7 ~]#unset n;[[ "$n" =~ ^[[:digit:]]+$ ]] && echo true

[root@centos7 ~]#echo $?

1

[root@centos7 ~]#n=200;[[ "$n" =~ ^[[:digit:]]+$ ]] && echo digit

digit

bash的文件测试

    存在性测试

           -a FILE:同 -e

           -e FILE: 文件存在性测试,存在为真,否则为假

    存在性及类别测试

            -b FILE:是否存在且为块设备文件

            -c FILE:是否存在且为字符设备文件

            -d FILE:是否存在且为目录文件

            -f FILE:是否存在且为普通文件

            -h FILE 或 -L FILE:存在且为符号链接文件

            -p FILE:是否存在且为命名管道文件

            -S FILE:是否存在且为套接字文件

bash的文件权限测试

     文件权限测试:

            -r FILE:是否存在且可读

            -w FILE: 是否存在且可写

            -x FILE: 是否存在且可执行

     文件特殊权限测试:

           -u FILE:是否存在且拥有suid权限

           -g FILE:是否存在且拥有sgid权限

           -k FILE:是否存在且拥有sticky权限

bash的文件属性测试

      文件大小测试:

           -s FILE: 是否存在且非空

      文件是否打开:

           -t fd: fd 文件描述符是否在某终端已经打开

           -N FILE:文件自从上一次被读取之后是否被修改过

           -O FILE:当前有效用户是否为文件属主

           -G FILE:当前有效用户是否为文件属组

bash的组合测试条件

      第一种方式:

          EXPRESSION1 -a EXPRESSION2 并且     

          EXPRESSION1 -o EXPRESSION2 或者

          ! EXPRESSION

          必须使用测试命令进行,[[ ]] 不支持

     第二种方式:

         COMMAND1 && COMMAND2 并且,短路与,代表条件性的AND THEN

         COMMAND1 || COMMAND2 或者,短路或,代表条件性的OR ELSE

         ! COMMAND 非

         如:[ -f “$FILE” ] && [[ “$FILE”=~ .*\.sh$ ]]        # -f 判断是否存在且为普通文件

以上参数多练习才能记住!!!!!

=====================================================================  

判断文件是否存在;

FILE=f.sh; [[ $FILE =~ \.sh$ ]] && echo sh

条件性的执行操作符

       

      ping -c1 -W2 station1 &> /dev/null \    -W2 超时时长,2秒ping不通,提示不成功 ; c1  ping一次

bash的组合测试条件

     

      test “$A”-eq “$B” && echo "Integers are equal“  eq 数字之间的比较,并不是相等的含义

      [ "$A" -eq "$B" ] && echo "Integers are equal“

      上面两种写法等价 eq 用来比较数字

      test "$A" = "$B" && echo "Strings are equal"

      [ "$A" = "$B" ] && echo "Strings are equal"

      上面两种写法等价,= 是用来比较字符串

    

     [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab   -f 存在且为普通文件   -a 并且    -x 是否存在且为可执行

     其中 -x 已经判断存在性问题,所以前面-f 可以省略,测试省略-f ,效果一样

     [ -z “$HOSTNAME” -o $HOSTNAME "=="localhost.localdomain" ] \

    && hostname www.magedu.com

    判断HOSTNAME变量是否为空, 或者是否等于域名,那么输出后面的命令

    [[]]  可以用 ==  ,一般用户正则表达式

==========================================================================

比如我们rm 一个文件,系统会提示是否删除,避免了一些操作带来的影响

read:使用read命令来接受输入

具体用法可以参照  help read

read: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]

    Read a line from the standard input and split it into fields.

    Reads a single line from the standard input, or from file descriptor FD

    if the -u option is supplied.  The line is split into fields as with word

    splitting, and the first word is assigned to the first NAME, the second

    word to the second NAME, and so on, with any leftover words assigned to

    the last NAME.  Only the characters found in $IFS are recognized as word

    delimiters.

   使用read来把输入值分配给一个或多个shell变量

      -p 指定要显示的提示

      -s 静默输入,一般用于密码

      -n N 指定输入的字符长度N

      -d ‘字符’ 输入结束符

      -t N TIMEOUT为N秒

      read 从标准输入中读取值,给每个单词分配一个变量

      所有剩余单词都被分配给最后一个变量

      read -p “Enter a filename: “ FILE

如果没有跟变量名,键入 read ,默认是在REPLY里

     [root@centos7 ~]#read

         def

     [root@centos7 ~]#echo $REPLY

        def

[root@centos7 ~]#cat read.sh

     echo -e "Please  input your name: \c"    -e 启用反斜杠转义   \c 压缩

     read NAME

     echo your name is $NAME

或者下面这样写,等价

    read -p "Please  input your name: " NAME

    echo your name is $NAME

  鸡兔同笼问题

  cat chook_rabbit.sh

      read -p "Input head number: " head

      read -p "Input head number: " foot

      rabbit=$[foot/2-head]

      chook=$[head-rabbit]

      echo "rabbit:$rabbit chook:$chook"

echo a b c  |read x y z

多次赋值,由于linux中管道的机制,每个管道执行,都会进入一个子shell中,下面两种写法都可以

echo 1 2 3 | { read x y z ; echo $x $y $z}

1 2 3

echo 1 2 3 | ( read x y z ; echo $x $y $z )

1 2 3

查看进程BASHPID 更明显的可以看出,管道的含义

[root@centos7 ~]#echo $BASHPID

56145

[root@centos7 ~]#echo $BASHPID |echo $BASHPID

53985

判断YES/No

vim yesorno.sh

read -p "Input [Yes/No]:" ANSWER

[[ "$ANSWER" =~ ^[Yy]([Ee][Ss])?$ ]] && { echo ok ; exit; }

[[ "$ANSWER" =~ ^[Nn][Oo]?$ ]] && { echo ok ; exit; }

echo "Your input id false."

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值