编程
shell变量分为两类:用户自定义变量和系统预定义的特殊变量
用户自定义变量
-
变量名
用户自定义变量是最普通的shell变量。变量名是以字母或下划线开头,由字母、数组和画线组成。
🧐数字不能做变量开头,大写字母通常是系统默认的变量,用户自定义变量通常用小写字母 -
变量赋值
一般形式:变量名=字符串
🧐等号两边不能有空格,若出现则赋值失败,变量未被赋值,则为空。若字符串一定要包括空格,字符串要加上引号[root@ localhost ~]# name=“Zhang San”
-
变量引用
在程序中使用变量的值时,在变量名前面加上“$”符,表示使用变量的值。[root@ localhost ~]# $name
🧐变量的引用会出现歧义
[root@ localhost~]# dir=/home/student [root@ localhost~]# cat $dir01/file1
在home目录下,是以student开头加学好的学生账户,所以第二行代码本意是要显示/home/student01/file1文件,但shell默认识别到第一个非法变量名字符为止,而这里第一个非法变量名字符是“/”,所以shell认为变量名为dir01,而该变量名的值为空,所以命令执行失败。要正确饮用变量,需要用大括号{}将该变量名括起来
[root@ localhost~]# cat ${dir}01/file1
除了用大括号,还可以用引号引用变量
[root@ localhost~]# cat “$dir”01/file1
🥸⚠️大括号不要错写成小括号,$()等价于倒引号,其作用是把括号内命令的执行结果赋值给变量
[root@ localhost~]# dir=$(pwd)
将当前工作的绝对路径赋值给dir
✌🏻数组的定义:
数组的定义和使用与变量相似,bash仅支持一维数组,并且没有限定数字的大小,数组的元素下标可以是整数或算数表达式,其值应大于或等于0。
在bash中,用括号来表示数组,数组元素用空格符号分隔
array name=(value1 … valuen)
eq:
array city=(beijing shanghai guangzhou)
还可以用declare命令显式声明一个数组,而不赋值
declare -a city
🤟🏻
读取数组:
格式是“${数组名[下标]}”
若没有给出元素的下标,则数组名表示下标为0的数组元素
若需要读取整个数组,则需要使用 * 或@作为下标,即
echo ${city[ * ]}
echo ${city[@]}
他们的区别在于,*将整个数组扩展为一个词(即字符串),这个词由以空格分开的各个数组元素组成;@将整个数组扩展为多个词,每个数组元素是一个词[root@ localhost ~]# name=(“zhang san” li si” “wang we”) [root@ localhost ~]# for i in “${name[*]}; do echo $i;done zhang san li si wang wu [root@ localhost ~]# for i in “${name[@]}; do echo $i;done zhang san li si wang wu
系统预定义变量
系统预定义变量是在shell中已定义好的变量
- $?
是上一条命令执行后的返回值
它是一个十进制数。大多数的shell命令执行成功后,返回值为0;执行失败,则返回非0值(除了let命令计算表达式的值) - $$
表示当前进程的进程号
每个进程都有唯一的进程号(PID),所以利用$ $可以证明脚本是在当前交互shell的子shell中运行。 - $!
上一个后台命令对应的进程号 - $-
当前在运行shell程序的选项 - $# $* $@
这三个变量都和位置参数有关
以下详解
位置参数变量
在Linux命令行中,后面可以跟多个参数,我们可以使用位置参数变量来代表这些参数。
-
$n
其中$0代表命令行本身,$1代表第1个参数,$2代表第2个参数,以此类推,当超过10时要用大括号括起来 ${10}[root@ localhost ~]# cat file1 file2
cat对应$0,$1对应file1,$2对应file2
位置参数变量用于向命令或程序脚本传递信息
[root@ localhost ~]# cat add #! /bin/bash let num1=$1 let num2=$2 let sum=num1+num2 echo $sum
运行该脚本:
[root@ localhost ~]# add 1 2
显然在实际问题中,add可以带多个参数,在不确定参数个数时,脚本就需要用到循环语句,这时用$#解决问题
-
$#
命令行上参数的个数
修改后的add如下:[root@ localhost ~]# cat add #! /bin/bash let sum=0 for((i=1;i<$#;i++)) do let sum=sum+$i done echo $sum
🤓除了$#来控制循环次数,还可以用shift来解决这个问题。shift命令移动位置参数,每执行一次shift命令,就把命令行上的实参向左移动一位。注意shift命令不能将$0移走。
[root@ localhost ~]#cat sh #! /bin/bash echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} shift echo $0 $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} [root@ localhost ~]#./sh05 a b c d ./sh05 a b c d ./sh05 b c d
-
$* $#
先来看下面的脚本:[root@ localhost ~]#vi sh03 #! /bin/bash echo “A total of $# parameters” echo “The parameters is: $*” echo “The parameters is: $@“
执行此脚本:
[root@ localhost ~]# ./sh03 11 22 33 A total of 3 parameters The parameters is:11 22 33 The parameters is:11 22 33
区别:
$*:会把接受到的所有参数当成一个整体
$@:会区别对待接收到的所有参数
例如:[root@ localhost ~]#cat sh04 #! /bin/bash for i in “$*” do echo “The parameters is:$i” done
执行该脚本
[root@ localhost sh]#./sh04 11 22 33 The parameters is:11 22 33
接下来用“$@”执行以下:
[root@ localhost ~]#cat sh04 #! /bin/bash for i in “$@” do echo “The parameters is:$i” done
执行该脚本
[root@ localhost ~]#./sh05 11 22 33 The parameters is:11 The parameters is:22 The parameters is:33
环境变量
环境变量也是系统预定义变量
环境变量和用户自定义变量还有一个主要区别在于,环境变量是全局变量,而用户自定义变量是局部变量。用户自定义变量是当前的shell中生效,而环境变量会在当前shell和这个shell的所有子shell中生效。
环境变量是写入相应配置文件的,在执行过程中修改环境变量修改的是进程内存中的变量值,而没有写入配置文件,所以当前shell结束,这个环境变量的修改就会结束,而只有写入配置文件才会在所有shell中生效。
在Linux中,一般通过环境变量配置操作系统的环境,如提示符、查找命令的路径、查找命令的路劲、用户家目录等,这些系统默认的环境变量的变量名是固定的,一些环境变量为只读变量,只读变量的值通常是在登录过程中定义的;而另外一些为非只读变量,可以修改。
环境变量一般都大写。
在bash中可以用env命令列出已经定义的所有环境变量,下面举例主要的环境变量的使用
-
HOME
用户家目录的绝对路径
家目录是用户在开始工作时的位置
在一般情况下用户注册登录名为student,HOME的值就为/home/student
不管当前路径在哪,都可以用通过cd $HOME 或cd不带参返回用户家目录 -
PATH
shell查找命令的目录列表
PATH变量包含存放系统命令的绝对路径
通常,用户会在家目录下建一个bin目录,存放自己编写的所有可执行命令,把这个目录加入PATH变量中,如下:[root@ localhost ~]#PATH= $PATH: $HOME/bin
即在当前的命令查找路径下增加一个目录$HOME/bin,这样就可以像使用系统命令一样使用自己编写的变量,而不用再给出相对路径
注:系统是严格按照PATH变量值中的路径顺序来查找命令的,也就是说PATH变量值中的路径顺序决定了先从哪个目录查找,假如用户编写了一个ls命令,放在 $HOME/bin,而且 $HOME/bin是PATH变量值中的第一个目录,则意味着用户输入ls命令,系统会执行用户编写的ls命令。 -
PS1
shell主提示符
主提示符是在shell准备接受命令时显示的字符串
PS1定义主提示符是怎样构成的,如果用户没有设置它,bash默认的主提示符如下:[root@ localhost~]# echo $PS1 [ \u@ \h\W]\$
系统默认只显示三项,即\u、\h、\W
“\u”表示当前用户的用户名
“\h”显示主机名的第一个字段(简称)
“\W”显示完整的工作目录,~代表家目录
在PS1中常用的转义字符及其含义如下:
\ $ :提示符,如果是root用户则为 # ,普通用户则为$
\t:显示时间为24小时格式,如“HH:MM:SS"
\T:显示时间内为12小时格式
\H:显示完整的主机名
\s:所有shell名称
\v:bash版本号 -
PWD
获取当前工作目录的绝对路径
指出目录在shell文件系统中处在什么位置,是由Linux自动设置的
可以通过下列命令获取当前路径[root@ localhost~]# echo $PWD
-
SHELL
当前使用的shell。
指出shell解释程序放在什么地方,例如,系统中默认的SHELL=/bin/bash,可以通过设置它来选择用户喜欢的SHELL
export命令设置变量作用域
环境变量和用户变量的作用域不同,可以通过export命令来设置
用户自定义变量是局部变量,仅限于自身范围,若希望父进程在创建子进程时将变量传递给子进程,需用export命令将这些变量送入进程转出区,然后被子进程继承,使用户自定义变量成为全局变量
[root@ localhost ~]# export 变量名
export命令声明的变量在当前shell和所有子shell中生效
[root@ localhost~]# name=zhang
[root@ localhost~]# bash
[root@ localhost~]# echo $name
第一句赋值是在父shell中执行的,在执行了bash语句后,处于子shell,在子shell中未对name变量赋值,所以name变量为空
[root@ localhost~]# exit
[root@ localhost~]# export name
[root@ localhost~]# bash
[root@ localhost~]# echo $name
这时变量name的值为zhang,子shell继承该变量
变量的查询和删除
-
unset注销变量
用户可以定义变量,在不需要时候也可以注销该变量[root@ localhost~]# unset 变量名
环境变量的删除方法和用户自定义变量是一样的。
-
set、env、export查询变量
三者都可查询系统当前已有的变量列表[root@ localhost~]# set
三者的区别:
set可以查询所有的变量,包括全局变量和局部变量
env命令可以查询所有的环境变老了,包括本进程及“祖先进程”所设置的全局(环境)变量
export命令可以显示本进程利用export所输出的全部变量在子shell中不能查询到父shell中自定义变量,但在子shell中能看到父shell的环境变量,这就是环境变量和用户自定义变量的区别。