shell中变量以及环境变量的常见用法

27 篇文章 0 订阅
16 篇文章 1 订阅

变量

变量类型
有两种类型的变量:局部变量和环境变量。局部变量仅在创建它的shell中有效,环境变量则对所有创建它的shell所派生出来的子进程都有效。某些变量由用户来创建,而另一些则是shell的特殊变量。
命名规则
变量名必须以字母或下划线开始,其余部分则可以由字符,数字(0-9)或下划线字符构成。而其他字符均可作为变量名的结束标志。名字是大写敏感的。当给一个变量赋值时,不要在等号两边留下空格。如果要将变量赋值为空,要在等号后直接跟一个换行符。创建局部变量的最简单方法时以下面的格式把值赋予变量
variable=value 例如 name=Tony
declare内置命令有两个内置命令declare和typeset可用于创建变量,通过选项还可以控制设置变量的方式。typeset命令(从Korn
shell而来)与declare命令完全一样。bash的文档中写道:typest命令完全兼容korn
shell,但是该命令并不支持内建命令声明。因此我们将使用declare内置命令。
没有参数的declare命令将列出所有设置的变量。通常只读变量时不能重新赋值或撤销的。如果有declare命令来创建只读变量,它们不能被撤销,也无法重新赋值。整型变量也能用declare来赋值。
declare variable=value declare name=Tony

declare选项

选项含义
-r将变量设置为只读
-x将变量名导出到子shell中
-i将变量置为整型
-a将变量当做数组,即给元素赋值
-F只列出函数名
-f列出函数名及其定义

Note:-a -F 只在bash2.x版本实现 局部变量和范围
变量的范围是指变量在一个程序中的什么地方是可见的。对于shell而言,局部变量的范围限于创建变量的shell。
当给一个变量赋值时,不要在等号两个留下空格。如果要将一个变量设置空,在等号后面跟一个换行符即可。
变量前面的美元符号用于提取其存储的值。
local函数可用于创建局部变量,但这些变量只能在函数内使用。
设置局部变量。局部变量可通过将值赋予一个变量名来设置,或者使用declare来设置。

$ round=world or declare round=world
$ echo $round
# world

$ x= #赋值为空值
$ echo $x
# 空值
$ file.txt=100
# wrong, 变量名中的字符只能是字母,数字和下划线
$ name="Tony Yang"
$ echo $name
# Tony Yang
# 引号用于隐藏空格,否则shell会把字符串分割为两个单词
$ echo $$
# 父进程id
$ round=world
$ bash
# 切换到子进程
$ echo $round
# 由于是局部变量,因此子进程无法访问该变量,结果为空行
$ exit # 退出子进程
$ echo $round
# 重新可以访问变量的值
$ bash
$ round=larry
$ echo $round
# 在子进程中定义一个同名变量,然后打印它的值world
$ exit
# 退出子进程
$ echo $round
# 打印的结果为父进程的变量值world

Note:set可以查看定义的变量,unset可以清空一个变量的值。子进程定义的变量,父进程无法访问。

$ name=Tony
$ readonly name
$ echo $name
#Tony
$ unset name
# 无法清空变量,因为name是只读变量
$ name=larry
# 无法设置新值,因为name是只读变量
$ declare -r name=tony
$ unset name
$ name=larry
# 结果同上面一样
环境变量

环境变量是能为创建它的shell及其派生子进程所用的变量,它们也经常被称为全局变量以区分与局部变量。一般约定环境变量为大写,它们是那些可以通过内置命令export导出的变量。
创建环境变量的shell称为父shell,从shell中启动的新shell称为子shell。环境变量被传送给任何从创建该变量的shell中派生的shell。这些变量可以从父shell传给子shell,再传给孙shell,以此类推,但反方向不行。即,shell能创建变量,但是它无法将变量传给其父shell,而只能传给它的子shell。某些环境变量,如HOME,LOGNAME,PATH已经SHELL,是在登录前由/bin/login程序来设置的。通常环境变量在用户主目录下的.bash_profile文件中定义。
设置环境变量
要设置环境变量,必须在给变量赋值或设置了变量后使用export命令,内置命令built-in加上-x选项也可以完成同样的事情(在导出一个变量时,不需要用美元符号)。

export variable=value
variable=value;export variable
declare -x variable=value

实例

$ export NAME=tony
$ PS1='\d:\W:$USER>';export PS1
$ declare -x TERM=linux

export命令选项

选项
选项段的结束标志,余下的都是参数
-fname-value 形式被视为函数而不是变量
-n将全局变量(已导出的)转换为局部变量,该变量将不会导出到子进程中
-p显示所有的全局变量

Note:变量的继承(派生)是单向的,只能由父传子)

$ export TERM=linux or declare -x TERM=linux
$ NAME="tony yang"
$ export NAME
$ echo $NAME

$ echo $$
$ bash
$ echo $$ # 子shell
$ echo $NAME # 依然可以访问从父shell继承的变量NAME
$ declare -x NAME="larry wall" # 在子shell中声明一个环境变量
$ echo $NAME
$ exit
$ echo $NAME #此时回到父shell,NAME的值依然为tony yang,因为环境变量是无法子传父的。
# tony yang

清空变量
如果未被设置为只读属性的话,本地变量和环境变量都可以通过使用unset命令清空

unset name; unset TERM
# unset把变量从shell内存中删除
$ declare num=100
$ set | grep num #可以查看到该变量
$ unset num; set | grep num # num变量被删除

打印变量的值:echo命令内建命令echo的作用是将其参数打印到标准输出。-e选项使得echo命令可以无限制地使用转义序列控制输出的效果。

echo选项含义

选项解释
-e允许翻译如下所有的转义序列
-n把换行符压缩到输出行的末尾
-E关闭对转义符号的翻译,包括关闭对那些默认情况下翻译的转义符号的翻译

转义序列

转义符解释
\a警告(铃声)
\b退格
\c不换行打印
\f填表
\n换行
\r返回
\t制表符
\v垂直制表符
\反斜杠
\nnmASCII代码为nmm的符号
$ echo The username is $LOGNAME
$ echo -e "\t\thello there\c"
# 打印转义序列已经字符串内容
$ echo -n "hello there"
# 打印行,不换行
$ echo -E "\t\thello world"
# 打印行,关闭转义字符的解释,安装字面内容打印
# \t\thello world

printf命令.用来格式化输出,作用是用来打印格式化字符串,效果类似c语言的printf函数。格式包括字符串本身和描述打印效果的字符。定义格式的方法是在%后面跟一个说明符,例如%f表示后面是一个浮点数,%d表示一个整数。

格式 printf format [arguments...]

$ printf '%10.2f%5d\n' 10.5 25
#      10.50   25

$ type printf
# printf is a built-in

$ printf "The number is %.2f\n" 100
# The number is 100.00
$ printf "%-20s%-15s%10.2f\n" "jody" "savage" 28
# jody                savage              28.00

$ printf "%s's average was %.1f%%.\n" "jody" $(( (80 + 70 + 90)/3 ))
# jody's average was 80.0%.

变量扩展修改符(参量扩展)。通过特定的修改符,可以检验和修改变量。这些修改符提供了一个快捷的方法来检验变量是不是被设置过,并把输出结果输出到一个变量中。见下表
变量修改符

修改符解释
${variable:-word}如果变量被设置了而且非空(null)就保持原来的值,否则设置为word
${variable:=world}如果变量被设置了而且非空就保持原来的值,否则就把变量永久设置为word
${variable:+world}如果变量被设置了而且非空就替代word,否则什么也不做
${variable:?word}如果变量被设置了而且非空就保持原来的值,否则就打印word,然后退出shell。如果word为空就打印parameter null or not set
${variable:offset从offset位置开始提取变量的值得子字符串,如果offset为0就取整个字符串
${variable:offset:length从变量值的offset位置开始提取长度为length的子字符串

使用冒号和修改符来检验变量是否被设置,是否为空。若没有冒号,即使设置为null的变量也被认为是已被设置过值。

$ fruit=peach
$ echo ${fruit:-world}
# peach
$ echo ${newfruit:-apple}
# apple
$ name=
$ echo ${name:-joe}
# joe                #=> 这两种方法相同,结果一样
$ echo ${name:-joe}
# joe

$ echo $name
# 空值

Note: 以上这种方法只是临时赋值,并不会永久保存在name变量里面

$ name=
$ echo ${name:=peter}
# peter
$ echo $name
# peter

Note:
以上这种方法会永久赋值,会将值暂时的永久保留在变量里,除非手动清除或者赋新值

$ foo=grapes
$ echo ${foo:+apple}
# apple
$ echo $foo
# grapes

Note:以上这种方法与:-方法正好相反,当foo值不为null时,会临时改变它的值,但是不是永久改变,因此再次打印foo的时候,值依然是原来的grapes

$ echo ${namex:?"namex is undefined"}
# 因为namex为null,因此会打印后面的字符串内容即namex is undefined 
$ echo ${y:?} or echo ${y?}
# parameter null or not set
$ var=notebook
$ echo ${var:0:4}
# note
$ echo ${var:4:4}
# book
$ echo ${var:0:2}
# no

子字符串的变量扩展。模式匹配参数用来从字符串的前面或者后面,去掉特定的部分字符串。最常用的方法就是从路径中去点路径。

表达式功能
${variable%pattern}变量的值与模式符合smallest trailing portion就删除它
${variable%%pattern}变量的值与模式符合largest trailing portion就删除它
${variable#pattern}变量的值与模式符合smallest leading portion就删除它
${variable##pattern}变量的值与模式符合largest leading portion 就删除它
${#variable}替换变量中字母的个数,如果*或者@,长度就是位置参量的个数
$ pathname="/usr/bin/local/bin"
$ echo ${pathname%/bin*}
# 从尾部开始删除最小匹配的内容即/bin/
$ pathname = "/usr/bin/local/bin"
$ echo ${pathname%%/bin*}
# 从尾部开始删除最大匹配的内容即/bin/local/bin/
$ pathname="/home/tony/.bashrc"
$ echo ${pathname#/home}
# 从头开始,删除最小匹配的内容即/home
$ pathname="/home/tony/.bashrc"
$ echo ${pathname##*/}
# 从头开始,删除最大匹配的内容即/home/tony/
$ name="Ebenezer Scrooge"
$ echo ${#name}
# 打印赋值给变量name的字符串的字母个数,这里共有16个字母

位置参量。通常情况下,特定的内建变量,被称为位置参量,它们被用于从命令行向脚本传递参数,或者在函数中用于保存传递给函数的参数。这些变量称为位置参量是因为它们以数字1,2,3…区分,这些数字与它们在参量清单中的位置有对应关系。
shell脚本的名字保存在变量$0中,位置参量可以被set命令设置,重置和清空。

表达式功能
$0当前脚本的名字
$1-9位置参数1-9
${10}位置参量10
$#位置参量的个数
$*向所有的位置参量赋值
$@同$*, 有双引号时除外
“$*”赋值到"$1$2$3"等等
“$@”赋值到"$1" “$2” "$3"等等
$ set punky tommy bert jody
$ echo $*
# punky tommy bert jody
$ echo $@
# punky tommy bert jody
$ echo $#
# 4

$ set a b c d e f g h i j 
$ print $10
# a0 不会解释为$10,而是解释为$1 + 0,因此需要加上一个花括号来避免这种情况

$ set file1 file2 file3
$ eval echo \$$#
# file3 首先$#会被替换为3,然后eval会将字符串$3解释为位置参数$3,此时该变量的值为file3,因此结果为file3
$ set --
# 清空所有位置参量

其他特殊变量
shell有一些由单个字符组成的变量,在这些变量前加上$后就能访问这些变量,见表

变量含义
$shell的PID
-当前sh的选项
?最后一个命令的退出状态值
!最后一个放入后台作业的PID值
$ echo The pid of this shell is $$

$ echo "The options for this shell are $-"
# 打印当前交互式bash的选项
$ grep root /etc/passwd
$ echo $?
# 打印最后一个命令执行的退出状态值,成功返回0,失败返回1
$ sleep 10 &
$ echo $!
# 打印最后一个被放入后台的作业PID号
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值