变量基础知识程序由指令加数据所组成,而变量可以理解为数据来源的一种。 变量名可以理解为指向了某个内存空间的地址,对于变量的赋值可理解为向内存空间写入数据,对于变量的引用可理解为从内存空间读取数据。 变量有类型的概念(例如字符串、数字等),不同的类型决定了数据的存储格式、可表示的数据范围以及可参与的运算等。 在编程语言中,可以根据变量的强弱来划分。例如C语言属于强类型变量的语言,该类变量在类型不同的情况下无法直接进行运算。bash脚本则属于弱类型变量的语言,不同类型的变量可以直接运算,默认将所有的变量统一视为字符型,必须在借助第三方工具的情况下才可以进行浮点数的运算,变量无需事先声明即可使用(相当于把声明、赋值和定义数据类型的操作同时实现)。 变量的声明就是事先占用好这个内存空间。变量的强弱之分与是否需要事先声明无关,例如python是强变量类型的编程语言但是其变量不需要事先声明。 变量名可由字母、数字和下划线组成,并且不允许数字打头(几乎所有的编程语言均如此)。变量名要尽量做到见名知意,并且要有一定的规则,根据词语来划分(驼峰法、下划线法等),例如: my_favorite_sport="basketball" myFavoriteSport="basketball" 不要使用bash保留字来给变量命名,例如if、else、then等。 变量根据作用域可以划分为三种:
除了上述三种,还有位置参数变量和特殊变量:
本地变量本地变量的赋值与引用: 赋值:name=value
引用:${name}或者$name
在我们使用变量的时候,会遇到引号的情况,在bash中,引用(quoting)的作用是抑制bash对某些字符的特殊作用(例如美元符号$,就会做一些变量展开或者特殊符号的处理)。而引号则是引用的其中两种方式(单引号和双引号)。 单引号会使得其中的所有字符只有其字面意义,而双引号只会抑制大部分的特殊字符含义,但是不包括$等其他一些字符。 [root@c7-server ~]# name=zwl [root@c7-server ~]# echo '${name}' ${name} [root@c7-server ~]# echo "${name}" zwl 在引用变量的时候,也建议使用${name},因为这样子才可以支持bash的参数展开功能。 [root@c7-server ~]# echo ${name} alongdidi [root@c7-server ~]# echo ${name:2:3} ong [root@c7-server ~]# echo $name:2:3 alongdidi:2:3 我们可以通过set(bash内置命令)来查看已经设置的变量名称和值。不过set所显示出来的变量非常多,还包含了环境变量和函数,因此一般需要通过管道传输给less分页或者grep过滤。 ~]# set | grep "^name" name=alongdidi set还可以用于设置shell的属性(即工作特性)和位置参数,这里不展开。 当某个变量我们不要的时候,可以使用unset来将其取消掉。 [root@c7-server ~]# unset name [root@c7-server ~]# echo $name [root@c7-server ~]# set | grep "^name" [root@c7-server ~]# unset命令可以取消变量,也可以取消函数。 unset [-f] [-v] [name ...] -f:指明取消的name是函数。 -v:指明取消的name是变量。 这两个选项都可以省略,unset会首先尝试取消一个变量,若失败则再次尝试取消一个函数。某些变量无法被unset,例如只读变量。 可以通过shell内置命令readonly来将shell变量或者函数设置为只读的属性。 readonly [-aAf] [name[=value] ...]
readonly -p
第一种语法,是设置一个变量为只读变量并且可以选择是否赋值,如果此时不赋值,那么设置为只读后就无法再赋值或者改值了。 -a:指明name为索引数组(indexed array)。 -A:指明name为关联数组(associative array)。 -f:指明name为函数(function)。 [root@c7-server ~]# readonly age=28 [root@c7-server ~]# age=30 -bash: age: readonly variable [root@c7-server ~]# unset age -bash: unset: age: cannot unset: readonly variable -p:单独使用,显示出所有的只读变量和函数。 [root@c7-server ~]# readonly -p declare -r BASHOPTS="checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath" declare -ir BASHPID declare -r BASH_COMPLETION_COMPAT_DIR="/etc/bash_completion.d" declare -ar BASH_VERSINFO='([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")' declare -ir EUID="0" declare -ir PPID="3530" declare -r SHELLOPTS="braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor" declare -ir UID="0" declare -r age="28" 注意:declare -r就表示定义一个只读变量,这也是个shell内置命令,后面会提到。 我们刚说了,本地变量的作用域只在当前的shell中,那么在子shell和其他shell中应该是不存在的,我们来证明一下。 [root@c7-server ~]# pstree -ph 1148 sshd(1148)─┬─sshd(1851)───bash(1857) ├─sshd(3530)───bash(3536)───pstree(4859) └─sshd(4125)───bash(4131) [root@c7-server ~]# name=alongdidi [root@c7-server ~]# echo $name alongdidi [root@c7-server ~]# bash [root@c7-server ~]# pstree -ph 1148 sshd(1148)─┬─sshd(1851)───bash(1857) ├─sshd(3530)───bash(3536)───bash(4861)───pstree(4894) └─sshd(4125)───bash(4131) [root@c7-server ~]# echo $name [root@c7-server ~]# 我们原本在PID为3536的shell(bash进程)中,在当前shell设置了变量name并且可获取其值,随后使用bash命令进入了子shell(PID为4861的bash进程)中再获取这个变量,就获取不到了。 如果我们使用exit命令退回刚才的父shell,就又可以获取到该值。 [root@c7-server ~]# exit exit [root@c7-server ~]# echo $name alongdidi 我们切换使用Xshell再创建了一个新的session,在那个session下尝试获取该变量的值,也是没有的。证明成功。 [root@c7-server ~]# pstree -ph 1148 sshd(1148)─┬─sshd(1851)───bash(1857) ├─sshd(3530)───bash(3536) └─sshd(4125)───bash(4131)───pstree(4860) [root@c7-server ~]# echo $name [root@c7-server ~]# 本地变量的生命周期,从创建的时候开始,直到所在的bash进程结束(比如使用exit)或者变量被unset。 环境变量环境变量的作用域是当前shell及其子shell。因此也可以理解为将变量输出(export)到了子shell中。无论子shell的层数有几层,只要变量具备环境变量的属性,那么它就都会有值。 可以通过export或者declare将变量设置为环境变量。 [root@c7-server ~]# export name [root@c7-server ~]# bash [root@c7-server ~]# echo $name alongdidi [root@c7-server ~]# bash [root@c7-server ~]# echo $name alongdidi [root@c7-server ~]# bash [root@c7-server ~]# echo $name alongdidi export的语法如下。 export [-fn] [name[=value] ...]
export -p
-f:声明name是一个函数。 -n:去除环境变量的属性。 -p:使用该选项或者仅使用export命令的话,可以查看当前所有的环境变量。declare -x有同效。外部命令env和printenv也可以实现。 export是专门用于设置与环境变量属性相关的命令。declare是设置所有与变量相关的属性(只读、环境变量、整型、索引数组、关联数组)等等。
多命令执行;:分号,命令按顺序执行,执行完第一个再执行第二个,后一个命令的执行与否与前一个命令的执行成功与否无关。 ~]# COMMAND1; COMMAND2 &&:逻辑与,只有当COMMAND1执行成功的时候,才执行COMMAND2。类似于逻辑与运算,a && b,当a为1的时候(执行成功)还需要看b的值(即还需要执行b)才能决定整个表达式的值,如果a为0了,那么整个表达式必然为0,就不需要看b的值了(b就可以不执行),这也叫短路法则。 ~]# COMMAND1 && COMMAND2 ||:逻辑或,只有当COMMAND1执行失败的时候,才执行COMMAND2。 ~]# COMMAND1 || COMMAND2 |
|