变量
本地变量:类似于局部变量,只在当前shell进程有效
环境变量:适用于所有登录进程所产生的子进程
位置参数:用于向shell脚本传递参数,只读
变量替换和赋值
引用变量值就称为变量替换,$就为变量替换符号,如a为变量名则$a或${a}为变量值
将值赋给某个变量名就称为变量赋值,格式:variable=value或${ variable=value },如值中包含空格则必须用""
清除变量的值:
unset 变量名
设置只读变量:
variable=value
readonly variable
还可以用declare和typeset实现
查看系统中的所有只读变量:
[[email protected] tmp]# readonly
declare -ar BASH_VERSINFO=‘([0]="3" [1]="2" [2]="25" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")‘
declare -ir EUID="0"
...
变量赋值的模式
1.variable:?value或variable?value
对未赋值的variable显示系统错误
[[email protected] tmp]# echo ${a:?blue}
bash: a: blue
[[email protected] tmp]# a=black
[[email protected] tmp]# echo ${a:?blue}
black
2.variable:=value
对未赋值的variable,将value值赋给它
[[email protected] tmp]# a=black
[[email protected] tmp]# echo ${a:=blue}
black
[[email protected] tmp]# unset a
[[email protected] tmp]# echo ${a:=blue}
blue
[[email protected] tmp]# echo $a
blue
3.variable:-value
对未赋值的variable,返回value,但是variable仍未赋值
[[email protected] tmp]# unset a
[[email protected] tmp]# echo ${a:-blue}
blue
[[email protected] tmp]# echo ${a:?blue}
bash: a: blue
无类型的shell脚本变量
shell脚本变量是无类型的,并且同时具有数字型和字符型两种赋值,可以不用预定义变量而直接使用,数字型的初始值为0,字符型的初始值为空
[[email protected] tmp]# cat a.sh
#! /bin/sh
c=""
echo "c=$c"
let "c+=1" #let命令用于执行算数运算,let "c+=1"等价于c+=1
echo "c=$c"
echo "e=$e"
let "e+=1"
echo "e=$e"
e="hello" #此时该变量的数字值又变为0
echo "e=$e"
let "e+=2"
echo "e=$e"
[[email protected] tmp]# ./a.sh
c=
c=1
e=
e=1
e=hello
e=2
环境变量
父进程的环境变量可以传递给子进程,但是子进程的环境变量(或者修改了父进程定义的环境变量)传递不了也影响不了父进程
定义环境变量:
ENVIRON-VARIABLE=value
export ENVIRON-VARIABLE
习惯环境变量用大写
export表明此变量为环境变量
清除环境变量:
unset ENVIRON-VARIABLE
重要的环境变量:
1.PWD和OLDPWD
PWD记录当前目录,OLDPWD记录旧的工作目录
[[email protected] tmp]# echo $PWD
/tmp
[[email protected] tmp]# cd
[[email protected] ~]# echo $PWD
/root
[[email protected] ~]# echo $OLDPWD
/tmp
2.PATH
shell为每个输入命令搜索PATH中的目录列表
[[email protected] ~]# echo $PATH
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
[[email protected] ~]# export PATH=$PATH:/tmp/bin #添加新路径
[[email protected] ~]# echo $PATH
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin:/tmp/bin
3.HOME
用户家目录的路径
[[email protected] ~]# echo $HOME
/root
4.SHELL
保存默认的shell值(/bin/bash)
5.USER和UID
已登录用户的名字和已登录用户的ID
[[email protected] ~]# echo $USER $UID
root 0
6.PPID和$
$PPID当前进程的父进程号,$$为当前进程的进程号
7.PS1和PS2
分别为开头的提示符和分行的提示符(即命令分多行输入时的提示符)
[[email protected] ~]# echo $PS1
[\[email protected]\h \W]\$
[[email protected] ~]# echo $PS2
>
\u代表当前用户名
\h代表主机名
\H代表主机名和域名
\W代表当前工作目录的名字
\w代表当前工作目录的完整路径
\$ UID为0则显示#,否则打印$
8.IFS
指定shell的输入域分隔符,默认为空格
[[email protected] ~]# export IFS=" "
[[email protected] ~]# echo $PATH
/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin:/tmp/bin
[[email protected] ~]# export IFS=:
[[email protected] ~]# echo $PATH
/usr/kerberos/sbin /usr/kerberos/bin /usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin /usr/X11R6/bin /root/bin /tmp/bin
环境变量配置文件
在用户的根目录中,为隐藏文件
1. .bash_profile
用户登录时自动执行,初始化环境变量,如果不存在该文件则执行/etc/profile
可以自己加入新的环境变量,并且执行. .bash_profile或者source .bash_profile立即生效(注销也可以)
source命令等价于.命令
直接执行文件是启动一个子shell,而子shell脚本设置的环境变量无法影响当前shell脚本,soure命令(或.命令)让简本在当前shell执行
[[email protected] ~]# cat .bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
2. .bashrc
设置子shell的环境变量,使得用户登录时的环境变量设置与子shell的环境变量设置相分离,提高灵活性
3. .bash_logout
在用户注销时执行,可以写入清楚某些环境变量的命令,也可以不存在
export PATH
unset USERNAME
父进程,子进程环境变量关系
子进程能继承父进程的环境变量,但是子进程修改父进程的环境变量只对子进程有效,不影响父进程环境变量,子进程创建的环境变量父进程也接收不到,而本地变量则互不影响
例:
[[email protected] tmp]# cat father.sh
#! /bin/bash
fatherLocal="fatherLocal"
fatherEnviron="fatherEnviron"
export fatherEnviron
echo "in fahter.sh"
echo "father process ID is $$"
echo "fatherLocal is $fatherLocal"
echo "fatherEnviron is $fatherEnviron"
$PWD/child.sh
echo "return to father.sh"
echo "fatherLocal is $fatherLocal"
echo "fatherEnviron is $fatherEnviron"
[[email protected] tmp]# cat child.sh
#! /bin/bash
echo "in child.sh"
echo "child process ID is $$ and my father is $PPID"
echo "fatherLocal is $fatherLocal"
echo "fatherEnviron is $fatherEnviron"
echo "change faterEnviron"
export "fatherEnviron=redefinfatherEnviron"
echo "new fatherEnviron is $fatherEnviron"
结果:
[[email protected] tmp]# ./father.sh
in fahter.sh
father process ID is 29171
fatherLocal is fatherLocal
fatherEnviron is fatherEnviron
in child.sh
child process ID is 29172 and my father is 29171
fatherLocal is
fatherEnviron is fatherEnviron
change faterEnviron
new fatherEnviron is redefinfatherEnviron
return to father.sh
fatherLocal is fatherLocal
fatherEnviron is fatherEnviron
位置参数
$0 脚本名称
$1 第一个参数
${10} 第十个参数,从10开始要加{}
$# 参数个数
$*或[email protected] 所有参数,不包括$0
$$ 进程号
$PPID 父进程号
$? 退出状态,0表示没有错误,非0表示有错误
引用
引用是屏蔽特殊字符的特殊意义,而将其解释为字面意义
"" 引用除了美元符号($),反引号(``),反斜杠(\)之外的所有字符
‘‘ 引用除了‘‘本身的所有字符
`` 反引号,shell将反引号中的内容解释为系统命令
\ 反斜杠,屏蔽下一个字符的特殊含义
对于变量加双引号可以保留多个空格(还有换行),而不解释为字段的分隔符(IFS默认为空),即双引号有防止变量变分隔符的作用
例:
[[email protected] tmp]# a="a b c"
[[email protected] tmp]# echo $a
a b c
[[email protected] tmp]# echo "$a"
a b c
[[email protected] tmp]# echo ‘$a‘
$a
[[email protected] tmp]# echo ‘why can‘t I‘m you are‘
why cant Im you are
[[email protected] tmp]# echo "why can‘t I‘m you are"
why can‘t I‘m you are
命令替换
将命令执行的标准输出替换该命令所在的位置
反引号(``)和$()
$()命令可以嵌套
$()将\就是\,而反引号(``)将\解释为空格
利用反引号可以将其它语言执行的结果赋值给shell变量,从而用shell处理
例:
[[email protected] tmp]# echo \\
\
[[email protected] tmp]# echo $(echo \\)
\
[[email protected] tmp]# echo `echo \\`
#空白行
command `echo` #command代表任何命令,这里相当于不带参数
command "`echo`" #带空字符串参数
command `echo x y` #带两个参数,为x和y
command "`echo x y`" #带一个参数,为x y
转义
作用:
1.解除一些特殊字符的含义
2.单个\在命令行中为出现二级提示符,在shell脚本中同样适用
3.在echo、sed、awk等命令中让一些字母能够表达特殊含义
1.
variable="()\\{}\$\""
echo $variable
echo "$variable"
IFS=‘\‘ #改变输入变量分隔符
echo $variable
echo "$variable" #双引号有防止变量变分隔符的作用,保留变量分隔符
[[email protected] tmp]# ./a3.sh
()\{}$"
()\{}$"
() {}$"
()\{}$"
2.
2.1
[[email protected] tmp]# echo \
> hello world
hello world
2.2
[[email protected] tmp]# echo \ #echo可以用""也可以不用
> "hello world"
hello world
2.3
[[email protected] tmp]# echo "\" #注意这和前面两个存在本质的区别,这里的\转义了"导致缺少后",补全命令才结束,和2.4同
> hello world"
"
hello world
2.4
[[email protected] tmp]# echo "
> hello
> world"
hello
world
2.5
[[email protected] tmp]# variable=\
> hello world
bash: world: command not found #变量赋值如果有空格必须用引号
2.6
[[email protected] tmp]# variable=\
> "hello world"
[[email protected] tmp]# echo $variable
hello world
2.7
[[email protected] tmp]# cat a5.sh
#! /bin/bash
echo \ #单个/在shell脚本中同样适用
hello world
[[email protected] tmp]# ./a5.sh
hello world
3.
\后跟字母的特殊含义:
\n 新的一行
\r 返回
\t tab键
\v或\f 换行但光标忍停留在原来的位置(横坐标相同)
\b 退格键
\a 发出警报声
\0xx ASCII码0xx对应的字符
例:
[[email protected] tmp]# echo hello\b\101
hellob101
[[email protected] tmp]# echo $‘hello\b\101‘ #和-e ""基本等价
hellA
[[email protected] tmp]# echo -e "hello\b\0101" #注意\0101的0,没有0不能解析成ASCII码
hellA
[[email protected] tmp]# echo -e "hello\b\101"
hell\101
[[email protected] tmp]# echo -e hello\b\101 #注意-e没有""同样不能解析
hellob101
注意:
echo [选项] [字符串]
选项-e表示将转移符(\)后跟字符形成的特殊字符解释成特殊意义
选项-n表示输出文字后不换行:
[[email protected] tmp]# echo -n "hello"
hello[[email protected] tmp]#
第六章 shell学习之变量和引用