shell基础之一:变量、变量运算及条件测试

一:相关概念理解

编译型语言:c,c++

     源程序(文本文件)  预处理  编译  汇编  链接

     静态语言

解释型语言:python,bash由解释器全程参与运行过程,每次读取一行,运行一行

    源程序(文本文件)  解析器读取并执行

    动态语言

       Python:有编程库,程序控制结构,调用编程库完成程序编写

               库文件:功能模块,在编程中可通过其API调用 

编译器:gcc

解释器:bash  提供编程环境

       解释:

            词法分析

            语法分析

            语义分析


程序指令+数据

      算法+数据结构


对象式编程:以数据为中心,设计数据结构(类),程序服务于数据结构

过程式编程:以指令为中心,设计算法,数据服务于算法

    bash是过程式编程:     

                  顺序执行:逐个执行

                  选择执行:只执行其中一个分支

                  循环执行:一段代码执行多次

   bash没有库,整个程序几乎都要依赖于命令

脚本:使用bash提供控制机智,将期望执行的命令罗列于文本文件中

     

二、变量

      什么是变量?

变量本质是一段内存空间的名字。可以赋值,可以重复赋值

1、bash变量类别

本地变量:只对当前shell进程有效,对其它shell进程无效,包括当前shell的子进程

     变量赋值:向变量的存储空间保存数据   VAR_NAME=VALUE

     变量引用:${VAR_NAME} 

           “”:弱引用,里面的变量会被替换

            '':强引用,里面的所有字符都是字面量,直接输出。所见即所得,不会变咯

[root@xxj shell]# name=xxj
[root@xxj shell]# echo "$name"
xxj
[root@xxj shell]# echo '$name'
$name
[root@xxj ~]# pstree                     #显示当前系统的进程树
init─┬─atd
     ├─auditd───{auditd}
     ├─crond
     ├─dbus-daemon
     ├─master─┬─pickup
     │        └─qmgr
     ├─6*[mingetty]
     ├─rsyslogd───3*[{rsyslogd}]
     ├─sshd───sshd───bash───pstree
     └─udevd───udevd
[root@xxj ~]# bash                      #进入当前shell的子shell
[root@xxj ~]# pstree
init─┬─atd
     ├─auditd───{auditd}
     ├─crond
     ├─dbus-daemon
     ├─master─┬─pickup
     │        └─qmgr
     ├─6*[mingetty]
     ├─rsyslogd───3*[{rsyslogd}]
     ├─sshd───sshd─┬─bash───bash───pstree
     │             └─bash
     └─udevd───udevd

[root@xxj ~]# echo "$name"

[root@xxj ~]#


环境变量:对当前shell进程有效及其子shell有效,对其他shell无效

    定义:export VAR_NAME=VALUE

    导出:export VAR_NAME 

    撤销变量: unset VAR_NAME 

    只读变量: readonly VAR_NAME    不能重复赋值

[root@xxj ~]# name=xj
[root@xxj ~]# echo $name
xj
[root@xxj ~]# export name
[root@xxj ~]# pstree
init─┬─atd
     ├─auditd───{auditd}
     ├─crond
     ├─dbus-daemon
     ├─master───qmgr
     ├─6*[mingetty]
     ├─rsyslogd───3*[{rsyslogd}]
     ├─sshd─┬─sshd───bash
     │      └─sshd───bash───pstree
     └─udevd───udevd
[root@xxj ~]# bash
You have entered the system: 168.100.20 your username is: root
WARNING:Proceed with caution! Have any questions please contact the system administrator
[root@xxj ~]# pstree
init─┬─atd
     ├─auditd───{auditd}
     ├─crond
     ├─dbus-daemon
     ├─master───qmgr
     ├─6*[mingetty]
     ├─rsyslogd───3*[{rsyslogd}]
     ├─sshd─┬─sshd───bash
     │      └─sshd───bash───bash───pstree
     └─udevd───udevd
[root@xxj ~]# echo "$name"
xj
[root@xxj ~]# readonly name
[root@xxj ~]# name=xiexie
bash: name: readonly variable

 

用户可自定义,bash许多内置的环境变量

[root@xxj ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

export PATH=$PATH:/usr/local/apache/bin

[root@xxj ~]# echo $PS1
[\u@\h \W]\$

\u:显示当前用户名

\h:显示简写的主机名

\W:显示当前所在目录的最后一个目录

\H:显示完整的主机名

\w:显示当前所在目录的完整目录

\$:提示符


局部变量:对shell脚本中某代码片段有效,通常用于函数本地:

    定义: local VAR_NAME=VALUE

位置参数变量:$1,$2,$3、、、${10}

特殊变量

$0:脚本名称自身

$*脚本所有的参数,$*把所有的参数看成一个整体

$@:脚本所有的参数,把所有的参数区分对待

$#:脚本所有参数的个数

$?:命令执行状态返回值,上一条命令的执行状态,状态用数字来表示0-255,0表示成功,非0表示失败

[root@xxj shell]# cat 16.sh
#!/bin/bash
cat<<EOF
\$1 is $1
\$2 is $2
\$0 is $0
\$@ is $@
\$* is $*
\$# is $#
EOF
[root@xxj shell]# bash 16.sh 1 2
$1 is 1
$2 is 2
$0 is 16.sh
$@ is 1 2
$* is 1 2
$# is 2
[root@xxj shell]# echo $?
0


查看当前shell进程中的所有变量:set

查看当前shell进程中的所有环境变量:export,printenv,env


变量命名

    1、不能使用程序中的关键字(保留字)如,if,case,for

    2、只能使用数字,字母和下划线,且不能以数字开头

    3、建议要见名知义


2、变量类型

变量类型:

  数值型:

     精确数值:整数

     近似数值:浮点型

          单精度浮点

          双精度浮点

  字符型:(ASCII)

        char

        string

        布尔型:true,false 1,0

定义变量类型的作用:

1、数据存储格式

2、数据的有效存储范围

3、比较机制不同

4、参与的运算类型不同

   (二进制)数字的存储,                 18:00010010    8个字节

    文本的存储,  ASCII:128常用字符       18:1,8       1:8bits   8:8bits   18:16bits   16个字节

    

类型转换:显示转换,隐式转换 

bash是弱类型语言,一切皆字符,可以隐式转换

       弱类型语言:

           1、不强制区分变量的类型

           2、无需事先声明,直接使用,直接赋值

bash变量的生命周期

            始于创建,终于销毁(shell进程终止或手动:unset NAME)


三、变量运算

bash中变量如何运算?

[root@xxj ~]# num1=4
[root@xxj ~]# num2=8
[root@xxj ~]# num=$num1+$num2
[root@xxj ~]# echo $num
4+8

为什么会这样?

因为bash中所有变量都默认是字符类型。

应该怎样进行运算呢?

1、在bash中使用变量运算可以事先申明变量的类型为数值型如下:

[root@xxj ~]# declare -i num1=4            
[root@xxj ~]# declare -i num2=8
[root@xxj ~]# num=$num1+$num2
[root@xxj ~]# echo $num 
12
[root@xxj ~]# declare -i num=$num1+$num2
[root@xxj ~]# echo $num
12
[root@xxj ~]# num3=3
[root@xxj ~]# num4=4
[root@xxj ~]# declare -i num=$num3+$num4
[root@xxj ~]# echo $num                       #发现“=”两边只要有一边定义了数值型就可以
7

2、也可以使用一些特定的格式:

[root@xxj ~]# let num=$num3+$num4
[root@xxj ~]# echo $num
7
[root@xxj ~]# echo $[$num3+$num4]
7
[root@xxj ~]# echo $(($num3+$num4))
7
[root@xxj ~]# expr $num3 + $num4
7

变量运算总结如下:

let VARNAME=算数表达式       圆整:如果计算结果中存在小数,将会被圆整

$[$num1+$num2]          

$(($num1+$num2))

expr $num1 + $num2      #注意,符号前后要有空格,可直接得到结果,

declare -i sum=$a+$b echo $sum

declare:

       -i:整型变量

       -x:环境变量,类似export


运算符:+,-,*,/,%(取余)

增强型赋值:+=,-=,*=,/=,%=

x=40

x=$[$x+2]

let x+=2

let x++ 相当于 let x+=1 

[root@xxj ~]# x=40
[root@xxj ~]# x=$[$x+2]
[root@xxj ~]# echo $x
42
[root@xxj ~]# x+=2
[root@xxj ~]# echo $x
422
[root@xxj ~]# let x+=2
[root@xxj ~]# echo $x
424
[root@xxj ~]# declare -i x+=2
[root@xxj ~]# echo $x
426
[root@xxj ~]#

四、条件测试

界定程序执行环境

    1、根据运行的命令的状态结果

    2、测试表达式

     test 测试表达式

     [ EXPRESSION ]  命令

     [[ EXPRESSION ]] 关键字, 通用性更好


整数测试做数值大小比较,所有不要给变量引用加引用

    $A -gt $B:是否大于,是则为真,不是则为假

    $A -ge $B:是否大于等于

    A -lt B:是否小于

    A -le B:是否小于等于

    A -eq B:是否等于

    A -ne B:是否不等于

[root@xxj shell]# num1=1
[root@xxj shell]# num2=2
[root@xxj shell]# [ $num1 -lt $num2 ]
[root@xxj shell]# echo $?
0
[root@xxj shell]# [[ $num1 -lt $num2 ]]
[root@xxj shell]# echo $?
0
[root@xxj shell]# [ $sum1-lt$sum2 ]  
[root@xxj shell]# echo $?
0
[root@xxj shell]# test $num1 -lt $num2   
[root@xxj shell]# echo $?
0
[root@xxj shell]# test $num1 -gt $num2  
[root@xxj shell]# echo $?
1

 

字符串测试

    "$A">"$B":是否大于    ASII数值越大,字符比较越大 注意使用[[ EXPRESSION ]]

    "$A"<"$B":是否小于

  "$A" == "$B":是否等于;

  "$A" != "$B":是否不等于;

      -z "$A":是否为空;空则为“真”,否则为“假”

      -n "$A":是否不空;不空则“真”,空则为“假”

           =~:字符串测试    模式匹配测试:[[ "string" =~ PATTERN ]]  #经测试不[[]]不能使用-a,-o,只支持扩展正则表达式

[root@xxj shell]# a=hello
[root@xxj shell]# b=name
[root@xxj shell]# [ $a -gt $b ]
-bash: [: hello: integer expression expected
[root@xxj shell]# ^C
[root@xxj shell]# [[ $a -gt $b ]]
[root@xxj shell]# echo $?
1
[root@xxj shell]# [[ $a -lt $b ]]              
[root@xxj shell]# echo $?                   #发现字符串测试并不能用整数测试的表达式
1
[root@xxj shell]# [ $a < $b ]               
-bash: name: No such file or directory
[root@xxj shell]# [[ $a < $b ]]            #字符串测试一定要用“[[ EXPRESSION ]]”
[root@xxj shell]# echo $?
0
[root@xxj shell]# [[ $a > $b ]]   
[root@xxj shell]# echo $?
1

[root@xxj shell]# [[ $a<$b ]]  
[root@xxj shell]# echo $?
0
[root@xxj shell]# aa=nihao
[root@xxj shell]# bb=nihao
[root@xxj shell]# [ $a == $b ]
[root@xxj shell]# echo $?
1
[root@xxj shell]# [[ $a == $b ]]
[root@xxj shell]# echo $?       
1
[root@xxj shell]# [ $aa == $bb ] 
[root@xxj shell]# echo $?       
0
[root@xxj shell]# [ $aa = $bb ]     # “=”和“==”有区别吗???
[root@xxj shell]# echo $?      
0
[root@xxj shell]# [[ $aa = $bb ]]
[root@xxj shell]# echo $?        
0
[root@xxj shell]# [[ -z $aa  ]]     
[root@xxj shell]# echo $?      
1
[root@xxj shell]# [ -z $aa  ]
[root@xxj shell]# echo $?    
1
[root@xxj shell]# [ -n $aa  ] 
[root@xxj shell]# [[ -z $aa  ]]
[root@xxj shell]# echo $?      
1
[root@xxj shell]# [ -z $aa  ]    #发现字符比较中除了奇葩的比较大小外“[]”和“[[]]”是通用的
[root@xxj shell]# echo $?    
1

 

文件测试:测试文件是否存在性以及属性

-e $file:文件是否存在,存在为真

-a $file:文件是否存在

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

-d $file:是否存在且为目录

-L $file:是否存在且为链接文件

-h $file:是否存在且为链接文件

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

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

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

-p $file:是否存在且为管道文件


-r $file:当前用户对文件是否拥有读权限

-w $file:写

-x $file:执行

-u $file:SUID

-g $file:SGID

-k $file:sticky


-O $file:当前用户是否为文件的属主

-G $file:属组


双目操作符

   $file1 -nt $file2: file1是否新于file2, file1的最近一次的修改时间戳是否晚于file2的;

                      经测试比较的mtime即文件内容修改的时间也就是ls显示的时间

   $file1 -ot $file2: file1是否旧于file2, 

   $file1 -ef $file2:file1与file2是否指向了同一个inode;测试二者是否为同一个文件的硬链接;

[root@BAIYU_207 ~]# [ -f /etc/fstab ]
[root@BAIYU_207 ~]# echo $?
0
[root@BAIYU_207 ~]# [ -c /dev/null ]
[root@BAIYU_207 ~]# echo $?
0
[root@BAIYU_207 ~]# [ -b /dev/cdrom ]
[root@BAIYU_207 ~]# echo $?
0


组合测试条件

   条件间逻辑运算:与,或,非

       表达式组合:

             与:[ CONDITION1 -a CONDITION2 ]

              或:[ CONDITION1 -o CONDITION2 ]

              非: [[ ! CONDITION ]]

        命令组合:

            COMMAND1 && COMMAND2  相当于: [ EXPR1 ] && [ EXPR2 ]

            COMMAND1 || COMMAND2

            ! COMMAND1

            COMMAND1 ; COMMAND2

[root@localhost ~]# [ -f /etc/fstab -a -b /dev/cdrom ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [[ -f /etc/fstab -a -b /dev/cdrom ]]    #发现并不能使用“[[ ]]”
-bash: syntax error in conditional expression
-bash: syntax error near `-a'

[root@localhost ~]# [[ -f /etc/fstab -o -b /dev/cdrom ]]   
-bash: syntax error in conditional expression
-bash: syntax error near `-o'
[root@localhost ~]# [[ ! -f /etc/fstab ]]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [[ ! -f /etc/sysconfig ]]
[root@localhost ~]# echo $?
0
[root@localhost ~]# echo "aaaa" ||  echo "bbbb" && echo "cccc"
aaaa
cccc
[root@localhost ~]# echo $?
0
[root@localhost ~]# echo "aaaa" &&  echo "bbbb" ||  echo "cccc"       
aaaa
bbbb
[root@localhost ~]# echo $?
0
[root@localhost ~]# ecaho "aaaa" &&  echo "bbbb" ||  echo "cccc"
-bash: ecaho: command not found
cccc
[root@localhost ~]# echo $?
0
[root@localhost ~]# eacho "aaaa" ||  echo "bbbb" && echo "cccc"
-bash: eacho: command not found
bbbb
cccc
[root@localhost ~]# echo $?
0
[root@localhost ~]# eacho "aaaa" ||  echao "bbbb" && echo "cccc"
-bash: eacho: command not found
-bash: echao: command not found
[root@localhost ~]# echo $?
127


你可能感兴趣的:(bash,变量及变量运算)