《LInux与Unix Shell编程指南》笔记之环境与Shell变量
环境与shell变量
点击打开本章pdf文档
本地变量
本地变量在用户现在的shell生命期的脚本使用。例如一个本地变量LOCAL_VAL。这个值只在用户当前shell生命期
有意义。如果在shell中启动另一个进程或退出,此值将无效。这个方法的有点是用户不能对其他的shell或进程设置此
变量有效。
设置变量格式为:
variable-name=value 或 ${variable-name=value}
等号两边可以有空格,如果value中有空格,那么这个value要用双引号括起来。
变量设置时的不同模式
将变量并排可以使变量结合在一起。
使用unset命令清除变量。
如果未设置或初始化,就可以使用另一值。格式为:
下面的例子使用变量保存文件拷贝的文件名:
如果设置变量时,不想再改变其值,可以将之设置为只读方式,如:
使用set命令,如:
环境变量
环境变量用于所有用户进程(经常称为子进程)。登录进程成为父进程。shell中执行的用户进程均成为子进程。不
像本地变量(只用于现在的shell)环境变量可用于所有子进程。用户注销时这些值将丢失。环境变量应用于用户进程时,
必须用export命令导出。环境变量与本地变量设置方式相同。
a、设置和显示环境变量:
嵌入shell变量
预留的环境变量名,这些变量名不能用作其他用途。列举一下嵌入变量列表:
1、CDPATH
改变目录路径,用于cd命令,如果设置了CDPATH,cd一个目录时,首先查找CDPATH,如果CDPATH指明了该目录,
则此目录成为当前工作目录。如目录E在/root/C/E,那么应该设置为:
可以添加多个目录,用“:“号分开,如:
保存vi编辑器时的初始化选项。例如,调用vi时,要显示行号,命令为:
3、HOME
用cd命令进入:
此变量保存登录名,一般为缺省值,但也可以设置:
变量保存邮箱路径名,如:
缺省每60s检查新邮件,如:
保存进行命令或脚本查找的目录顺序,如:
8、PS1
基本提示符包含shell提示符,缺省对超级用户为#,其他为$。可以修改为:
附属提示符,缺省为符号>。用于执行多行命令或超过一行的一个命令。如:
SHELL变量保存缺省shell,通常在/etc/passwd/中已设置。
终端初始化变量保存终端配置文件的位置。
10、TERM
保存终端类型。
11、TZ
时区变量保存时区值,只有系统管理员才能够更改。
将变量导出到子进程
shell新用户碰到的问题之一是定义的变量如何导出到子进程。前面已经讨论过环境变量的工作方式,现在用脚本实现
它,并在脚本中调用另一脚本(这实际上创建了一个子进程)。
以下是两个脚本列表 father和child。
father脚本设置变量film,取值为 A Few Good Men ,并将变量信息返回屏幕,然后调用脚本child ,这段脚本
显示第一个脚本里的变量 film,然后改变其值为 Die Hard ,再将其显示在屏幕上,最后控制返回 father 脚本,再次
显示这个变量。
father文件:
,以便child脚本知道film变量的取值,才会工作。
4中变量,本地、环境,还有位置变量和特定变量参数因为他们是只读的。
位置变量
如果要向一个shell脚本传递信息,可以使用位置参数完成此功能。参数相关数目传入脚本,此数目可以任意多,但只
有前 9个可以被访问,使用shift命令可以改变这个限制。
参数从第一个开始,在第 9个结束;每个访问参数前要加 $ 符号。第一个参数为 0,表示预留保存实际脚本名字。无论
脚本是否有参数,此值均可用。
加入向脚本传送Did You See The Full Moon信息,解释为:
特定变量参数
特定shell变量
-----------------------------------------
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过9个
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的进程ID号
$@ 与$#相同,但是使用时加引号,并在引号中返回每个参数
$- 显示shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
-----------------------------------------
创建文件allparams:
例如,拷贝一个文件并检查是否成功:
点击打开本章pdf文档
本地变量
本地变量在用户现在的shell生命期的脚本使用。例如一个本地变量LOCAL_VAL。这个值只在用户当前shell生命期
有意义。如果在shell中启动另一个进程或退出,此值将无效。这个方法的有点是用户不能对其他的shell或进程设置此
变量有效。
设置变量格式为:
variable-name=value 或 ${variable-name=value}
等号两边可以有空格,如果value中有空格,那么这个value要用双引号括起来。
变量设置时的不同模式
variable
-
name
=
value 设置实际值到variable
-
name
variable - name + value 如果设置了variable - name,则重设其值
variable - name: ? value 如果未设置variable - name,显示未定义用户错误信息
variable - name ? value 如果未设置variable - name,显示系统错误信息
variable - name: = value 如果未设置variable - name,设置其值
variable - name: - value 同上,但是取值并不设置到Variable - name,可以被替换
a、显示变量variable - name + value 如果设置了variable - name,则重设其值
variable - name: ? value 如果未设置variable - name,显示未定义用户错误信息
variable - name ? value 如果未设置variable - name,显示系统错误信息
variable - name: = value 如果未设置variable - name,设置其值
variable - name: - value 同上,但是取值并不设置到Variable - name,可以被替换
[root@localhost
~
]# DOLLAR
=
99
[root@localhost ~ ]# echo ${DOLLAR}
99
b、结合变量[root@localhost ~ ]# echo ${DOLLAR}
99
将变量并排可以使变量结合在一起。
[root@localhost
~
]# FIRST
=
"
Bruce
"
[root@localhost ~ ]# SURNAME = " Willis "
[root@localhost ~ ]# echo ${FIRST}${SURNAME}
Bruce Willis
c、清除变量[root@localhost ~ ]# SURNAME = " Willis "
[root@localhost ~ ]# echo ${FIRST}${SURNAME}
Bruce Willis
使用unset命令清除变量。
unset variable
-
name
d、测试变量是否已经设置如果未设置或初始化,就可以使用另一值。格式为:
${variable:
-
value}
意思就是说如果设置了就使用这个设置了的值,如果没有设置,那么用-value。例如:
[root@localhost
~
]# COLOUR
=
blue
[root@localhost ~ ]# echo " The sky is ${COLOUR:-grey} today. "
The sky is blue today.
在这里COLOUR已经设置为blue,所以显示出来,下面清除这个值,然后测试:
[root@localhost ~ ]# echo " The sky is ${COLOUR:-grey} today. "
The sky is blue today.
[root@localhost
~
]# unset COLOUR
[root@localhost ~ ]# echo " The sky is ${COLOUR:-grey} today. "
The sky is grey today.
也可以编写脚本测试变量是否取值,然后返回带有系统错误信息的结果。例如,下面测试变量file是否取值:
[root@localhost ~ ]# echo " The sky is ${COLOUR:-grey} today. "
The sky is grey today.
[root@localhost
~
]# echo
"
The file is ${FILES:?}
"
bash: FILES: parameter null or not set
或者修改为:
bash: FILES: parameter null or not set
[root@localhost
~
]# echo
"
The file is ${FILES:?
"
sorry cannot local the variable
"
}
"
bash: FILES: sorry cannot local the variable
e、使用变量来保存系统命令参数bash: FILES: sorry cannot local the variable
下面的例子使用变量保存文件拷贝的文件名:
[root@localhost
~
]# SOURCE
=
"
.C/sh_test
"
[root@localhost ~ ]# DEST = " ./D/sh_test "
[root@localhost ~ ]# cp ${SOURCE} ${DEST}
[root@localhost ~ ]# cd D
[root@localhost D]# ls
sh_test
f、设置只读变量[root@localhost ~ ]# DEST = " ./D/sh_test "
[root@localhost ~ ]# cp ${SOURCE} ${DEST}
[root@localhost ~ ]# cd D
[root@localhost D]# ls
sh_test
如果设置变量时,不想再改变其值,可以将之设置为只读方式,如:
[root@localhost D]# TAPE_DEV
=
"
TAPE_DEV_1
"
[root@localhost D]# echo TAPE_DEV_1
TAPE_DEV_1
[root@localhost D]# readonly TAPE_DEV
[root@localhost D]# TAPE_DEV = " TAPE_DEV_2 "
bash: TAPE_DEV: readonly variable
g、显示所有本地shell变量[root@localhost D]# echo TAPE_DEV_1
TAPE_DEV_1
[root@localhost D]# readonly TAPE_DEV
[root@localhost D]# TAPE_DEV = " TAPE_DEV_2 "
bash: TAPE_DEV: readonly variable
使用set命令,如:
[root@localhost D]#
set
BASH =/ bin / bash
BASH_ARGC = ()
BASH_ARGV = ()
... ...
BASH =/ bin / bash
BASH_ARGC = ()
BASH_ARGV = ()
... ...
环境变量
环境变量用于所有用户进程(经常称为子进程)。登录进程成为父进程。shell中执行的用户进程均成为子进程。不
像本地变量(只用于现在的shell)环境变量可用于所有子进程。用户注销时这些值将丢失。环境变量应用于用户进程时,
必须用export命令导出。环境变量与本地变量设置方式相同。
a、设置和显示环境变量:
[root@localhost D]# echo $CONSOLE
[root@localhost D]# CONSOLE = tty1;export CONSOLE
[root@localhost D]# echo $CONSOLE
tty1
b、显示所有环境变量[root@localhost D]# CONSOLE = tty1;export CONSOLE
[root@localhost D]# echo $CONSOLE
tty1
[root@localhost D]# env
SSH_AGENT_PID = 3851
CONSOLE = tty1
HOSTNAME = localhost.localdomain
c、清除命令跟清除本地变量一样SSH_AGENT_PID = 3851
CONSOLE = tty1
HOSTNAME = localhost.localdomain
嵌入shell变量
预留的环境变量名,这些变量名不能用作其他用途。列举一下嵌入变量列表:
1、CDPATH
改变目录路径,用于cd命令,如果设置了CDPATH,cd一个目录时,首先查找CDPATH,如果CDPATH指明了该目录,
则此目录成为当前工作目录。如目录E在/root/C/E,那么应该设置为:
[root@localhost
/
]# CDPATH
=
:root
/
C;export CDPATH
[root@localhost / ]# cd E
/ root / C / E
[root@localhost E]#
观察最后一行的目录为E。
[root@localhost / ]# cd E
/ root / C / E
[root@localhost E]#
可以添加多个目录,用“:“号分开,如:
[root@localhost
/
]# CDPATH
=
:root
/
C:root
/
D;export CDPATH
2、EXINIT保存vi编辑器时的初始化选项。例如,调用vi时,要显示行号,命令为:
[root@localhost E]# EXINIT
=
'
set nu
'
;export EXINIT
然后打开vi编辑器后会看到行号了。3、HOME
用cd命令进入:
[root@localhost root]# HOME
=/
home
/
balu;export HOME
[root@localhost root]# pwd
/ root
[root@localhost root]# cd
[root@localhost ~ ]# pwd
/ home / balu
4、LOGNAME[root@localhost root]# pwd
/ root
[root@localhost root]# cd
[root@localhost ~ ]# pwd
/ home / balu
此变量保存登录名,一般为缺省值,但也可以设置:
[root@localhost
/
]# echo $LOGNAME
root
[root@localhost / ]# LOGNAME = " zzc " ;export LOGNAME
[root@localhost / ]# echo $LOGNAME
zzc
5、MAILroot
[root@localhost / ]# LOGNAME = " zzc " ;export LOGNAME
[root@localhost / ]# echo $LOGNAME
zzc
变量保存邮箱路径名,如:
[root@localhost
/
]# echo $MAIL
/ var / spool / mail / root
6、MAILCHECK/ var / spool / mail / root
缺省每60s检查新邮件,如:
[root@localhost
/
]# echo $MAILCHECK
60
可以设置为每2分钟检查一次,命令为:
60
[root@localhost
/
]# MAILCHECK
=
120
;export MAILCHECK
[root@localhost / ]# echo $MAILCHECK
120
7、PATH[root@localhost / ]# echo $MAILCHECK
120
保存进行命令或脚本查找的目录顺序,如:
$PATH
=
$HOME
/
bin:.:
/
bin:
/
usr
/
bin;export PATH
上面顺序为首先查找HOME/bin目录,然后当前目录,然后是/bin,最后是/usr/bin。
8、PS1
基本提示符包含shell提示符,缺省对超级用户为#,其他为$。可以修改为:
[root@localhost
~
]# PS1
=
"
->
"
;export PS1
-> PS1 = " star trek: " ;export PS1
star trek:
9、PS2-> PS1 = " star trek: " ;export PS1
star trek:
附属提示符,缺省为符号>。用于执行多行命令或超过一行的一个命令。如:
[root@localhost
~
]# echo
"
> a "
a
[root@localhost ~ ]# echo $PS2
>
[root@localhost ~ ]# PS2 = " @: " ;export PS2
[root@localhost ~ ]# echo "
@:a "
a
8、SHELL> a "
a
[root@localhost ~ ]# echo $PS2
>
[root@localhost ~ ]# PS2 = " @: " ;export PS2
[root@localhost ~ ]# echo "
@:a "
a
SHELL变量保存缺省shell,通常在/etc/passwd/中已设置。
[root@localhost
~
]# echo $SHELL
/ bin / bash
9、TERMINFO/ bin / bash
终端初始化变量保存终端配置文件的位置。
10、TERM
保存终端类型。
11、TZ
时区变量保存时区值,只有系统管理员才能够更改。
将变量导出到子进程
shell新用户碰到的问题之一是定义的变量如何导出到子进程。前面已经讨论过环境变量的工作方式,现在用脚本实现
它,并在脚本中调用另一脚本(这实际上创建了一个子进程)。
以下是两个脚本列表 father和child。
father脚本设置变量film,取值为 A Few Good Men ,并将变量信息返回屏幕,然后调用脚本child ,这段脚本
显示第一个脚本里的变量 film,然后改变其值为 Die Hard ,再将其显示在屏幕上,最后控制返回 father 脚本,再次
显示这个变量。
father文件:
[root@localhost D]# cat father
echo " this is the father "
FILM = " A Fer Good Men "
echo " I like the film :$FILM "
. / child
echo " back to father "
echo " and the file is :$FILM "
child文件:
echo " this is the father "
FILM = " A Fer Good Men "
echo " I like the film :$FILM "
. / child
echo " back to father "
echo " and the file is :$FILM "
[root@localhost D]# cat child
echo " called from father..i am the child "
echo " file name is :$FILM "
FILM = " Die Hard "
echo " changing file to :$FILM "
结果显示为(在这之前可能要修改文件权限):
echo " called from father..i am the child "
echo " file name is :$FILM "
FILM = " Die Hard "
echo " changing file to :$FILM "
[root@localhost D]# .
/
father
this is the father
I like the film :A Fer Good Men
called from father..i am the child
file name is :
changing file to :Die Hard
back to father
and the file is :A Fer Good Men
可以看到father中并未导出变量film,因此child脚本中不能将film变量返回。需要在father中加入export命令
this is the father
I like the film :A Fer Good Men
called from father..i am the child
file name is :
changing file to :Die Hard
back to father
and the file is :A Fer Good Men
,以便child脚本知道film变量的取值,才会工作。
[root@localhost D]# cat father
echo " this is the father "
FILM = " A Fer Good Men "
echo " I like the film :$FILM "
export FILM
. / child
echo " back to father "
echo " and the file is :$FILM "
再运行father脚本:
echo " this is the father "
FILM = " A Fer Good Men "
echo " I like the film :$FILM "
export FILM
. / child
echo " back to father "
echo " and the file is :$FILM "
[root@localhost D]# .
/
father
this is the father
I like the film :A Fer Good Men
called from father..i am the child
file name is :A Fer Good Men
changing file to :Die Hard
back to father
and the file is :A Fer Good Men
this is the father
I like the film :A Fer Good Men
called from father..i am the child
file name is :A Fer Good Men
changing file to :Die Hard
back to father
and the file is :A Fer Good Men
4中变量,本地、环境,还有位置变量和特定变量参数因为他们是只读的。
位置变量
如果要向一个shell脚本传递信息,可以使用位置参数完成此功能。参数相关数目传入脚本,此数目可以任意多,但只
有前 9个可以被访问,使用shift命令可以改变这个限制。
参数从第一个开始,在第 9个结束;每个访问参数前要加 $ 符号。第一个参数为 0,表示预留保存实际脚本名字。无论
脚本是否有参数,此值均可用。
加入向脚本传送Did You See The Full Moon信息,解释为:
$
0
$
1
$
2
$
3
$
4
$
5
$
6
$
7
$
8
$
9
脚本名字 Did You See The Full Moon
例如创建脚本param
脚本名字 Did You See The Full Moon
[root@localhost test]# cat param
echo " This is the script name : $0 "
echo " This is the first parameter : $1 "
echo " This is the second parameter : $2 "
echo " This is the third parameter : $3 "
echo " This is the fourth parameter : $4 "
echo " This is the fifth parameter : $5 "
echo " This is the sixth parameter : $6 "
echo " This is the seventh parameter : $7 "
echo " This is the eight parameter : $8 "
echo " This is the ninth parameter : $9 "
运行(可能需要权限):
echo " This is the script name : $0 "
echo " This is the first parameter : $1 "
echo " This is the second parameter : $2 "
echo " This is the third parameter : $3 "
echo " This is the fourth parameter : $4 "
echo " This is the fifth parameter : $5 "
echo " This is the sixth parameter : $6 "
echo " This is the seventh parameter : $7 "
echo " This is the eight parameter : $8 "
echo " This is the ninth parameter : $9 "
[root@localhost test]# .
/
param Did You See The Full Moon
This is the script name : . / param
This is the first parameter : Did
This is the second parameter : You
This is the third parameter : See
This is the fourth parameter : The
This is the fifth parameter : Full
This is the sixth parameter : Moon
This is the seventh parameter :
This is the eight parameter :
This is the ninth parameter :
所以如果需要返回脚本名称可以为:
This is the script name : . / param
This is the first parameter : Did
This is the second parameter : You
This is the third parameter : See
This is the fourth parameter : The
This is the fifth parameter : Full
This is the sixth parameter : Moon
This is the seventh parameter :
This is the eight parameter :
This is the ninth parameter :
[root@localhost test]# cat param2
echo " Hello world this is $0 calling "
[root@localhost test]# . / param2
Hello world this is . / param2 calling
或者通过脚本向系统命令传递参数:
echo " Hello world this is $0 calling "
[root@localhost test]# . / param2
Hello world this is . / param2 calling
[root@localhost test]# cat findfile
find / - name $ 1 - print
[root@localhost test]# . / findfile passwd
/ usr / bin / passwd
/ etc / pam.d / passwd
/ etc / passwd
find / - name $ 1 - print
[root@localhost test]# . / findfile passwd
/ usr / bin / passwd
/ etc / pam.d / passwd
/ etc / passwd
特定变量参数
特定shell变量
-----------------------------------------
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过9个
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的进程ID号
$@ 与$#相同,但是使用时加引号,并在引号中返回每个参数
$- 显示shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
-----------------------------------------
创建文件allparams:
[root@localhost test]# cat allparams
echo " This is the script name : $0 "
echo " This is the first parameter : $1 "
echo " This is the second parameter : $2 "
echo " This is the third parameter : $3 "
echo " This is the fourth parameter : $4 "
echo " This is the fifth parameter : $5 "
echo " This is the sixth parameter : $6 "
echo " This is the seventh parameter : $7 "
echo " This is the eight parameter : $8 "
echo " This is the ninth parameter : $9 "
echo " The number of arguments passed : $# "
echo " Show all arguments : $* "
echo " Show me my process ID : $$ "
echo " Show me the arguments in quotes : $@ "
echo " Did my script go with any errors : $? "
运行:
echo " This is the script name : $0 "
echo " This is the first parameter : $1 "
echo " This is the second parameter : $2 "
echo " This is the third parameter : $3 "
echo " This is the fourth parameter : $4 "
echo " This is the fifth parameter : $5 "
echo " This is the sixth parameter : $6 "
echo " This is the seventh parameter : $7 "
echo " This is the eight parameter : $8 "
echo " This is the ninth parameter : $9 "
echo " The number of arguments passed : $# "
echo " Show all arguments : $* "
echo " Show me my process ID : $$ "
echo " Show me the arguments in quotes : $@ "
echo " Did my script go with any errors : $? "
[root@localhost test]# .
/
allparams Merry Christmas Mr.Lawrence
This is the script name : . / allparams
This is the first parameter : Merry
This is the second parameter :Christmas
This is the third parameter : Mr.Lawrence
This is the fourth parameter :
This is the fifth parameter :
This is the sixth parameter :
This is the seventh parameter :
This is the eight parameter :
This is the ninth parameter :
The number of arguments passed : 3
Show all arguments : Merry Christmas Mr.Lawrence
Show me my process ID : 20055
Show me the arguments in quotes : Merry Christmas Mr.Lawrence
Did my script go with any errors : 0
由上面的$?返回值可知,它可以用来判断脚本运行的成功与否,返回0表示成功,1表示错误:
This is the script name : . / allparams
This is the first parameter : Merry
This is the second parameter :Christmas
This is the third parameter : Mr.Lawrence
This is the fourth parameter :
This is the fifth parameter :
This is the sixth parameter :
This is the seventh parameter :
This is the eight parameter :
This is the ninth parameter :
The number of arguments passed : 3
Show all arguments : Merry Christmas Mr.Lawrence
Show me my process ID : 20055
Show me the arguments in quotes : Merry Christmas Mr.Lawrence
Did my script go with any errors : 0
例如,拷贝一个文件并检查是否成功:
[root@localhost test]# cp param pp
[root@localhost test]# echo $ ?
0
但是拷贝一个不存在的文件,返回错误,如:
[root@localhost test]# echo $ ?
0
[root@localhost test]# cp aaa bbb
cp: 无法 stat “aaa”: 没有那个文件或目录
[root@localhost test]# echo $
?
1
1