变量

本地变量:类似于局部变量,只在当前shell进程有效

环境变量:适用于所有登录进程所产生的子进程

位置参数:用于向shell脚本传递参数,只读

变量替换和赋值

引用变量值就称为变量替换,$就为变量替换符号,如a为变量名则$a或${a}为变量值

将值赋给某个变量名就称为变量赋值,格式:variable=value或${ variable=value },如值中包含空格则必须用""

清除变量的值:

unset 变量名

设置只读变量:

variable=value

readonly variable

还可以用declare和typeset实现

查看系统中的所有只读变量:

[root@localhost 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显示系统错误

[root@localhost tmp]# echo ${a:?blue}

bash: a: blue

[root@localhost tmp]# a=black

[root@localhost tmp]# echo ${a:?blue}

black

2.variable:=value

对未赋值的variable,将value值赋给它

[root@localhost tmp]# a=black

[root@localhost tmp]# echo ${a:=blue}

black

[root@localhost tmp]# unset a

[root@localhost tmp]# echo ${a:=blue}

blue

[root@localhost tmp]# echo $a

blue

3.variable:-value

对未赋值的variable,返回value,但是variable仍未赋值

[root@localhost tmp]# unset a

[root@localhost tmp]# echo ${a:-blue}

blue

[root@localhost tmp]# echo ${a:?blue}

bash: a: blue

无类型的shell脚本变量

shell脚本变量是无类型的,并且同时具有数字型和字符型两种赋值,可以不用预定义变量而直接使用,数字型的初始值为0,字符型的初始值为空

[root@localhost 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"

[root@localhost 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记录旧的工作目录

[root@localhost tmp]# echo $PWD

/tmp

[root@localhost tmp]# cd

[root@localhost ~]# echo $PWD

/root

[root@localhost ~]# echo $OLDPWD

/tmp

2.PATH

shell为每个输入命令搜索PATH中的目录列表

[root@localhost ~]# 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

[root@localhost ~]# export PATH=$PATH:/tmp/bin      #添加新路径

[root@localhost ~]# 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

用户家目录的路径

[root@localhost ~]# echo $HOME

/root

4.SHELL

保存默认的shell值(/bin/bash)

5.USER和UID

已登录用户的名字和已登录用户的ID

[root@localhost ~]# echo $USER $UID

root 0

6.PPID和$

$PPID当前进程的父进程号,$$为当前进程的进程号

7.PS1和PS2

分别为开头的提示符和分行的提示符(即命令分多行输入时的提示符)

[root@localhost ~]# echo $PS1

[\u@\h \W]\$

[root@localhost ~]# echo $PS2

>

\u代表当前用户名

\h代表主机名

\H代表主机名和域名

\W代表当前工作目录的名字

\w代表当前工作目录的完整路径

\$ UID为0则显示#,否则打印$

8.IFS

指定shell的输入域分隔符,默认为空格

[root@localhost ~]# export IFS=" "

[root@localhost ~]# 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

[root@localhost ~]# export IFS=:

[root@localhost ~]# 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执行

[root@localhost ~]# 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

父进程,子进程环境变量关系

子进程能继承父进程的环境变量,但是子进程修改父进程的环境变量只对子进程有效,不影响父进程环境变量,子进程创建的环境变量父进程也接收不到,而本地变量则互不影响

例:

[root@localhost 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"

[root@localhost 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"

结果:

[root@localhost 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开始要加{}

$# 参数个数

$*或$@ 所有参数,不包括$0

$$ 进程号

$PPID 父进程号

$? 退出状态,0表示没有错误,非0表示有错误

引用

引用是屏蔽特殊字符的特殊意义,而将其解释为字面意义

"" 引用除了美元符号($),反引号(``),反斜杠(\)之外的所有字符

'' 引用除了''本身的所有字符

`` 反引号,shell将反引号中的内容解释为系统命令

\ 反斜杠,屏蔽下一个字符的特殊含义

对于变量加双引号可以保留多个空格(还有换行),而不解释为字段的分隔符(IFS默认为空),即双引号有防止变量变分隔符的作用

例:

[root@localhost tmp]# a="a       b       c"

[root@localhost tmp]# echo $a

a b c

[root@localhost tmp]# echo "$a"

a       b       c

[root@localhost tmp]# echo '$a'

$a

[root@localhost tmp]# echo 'why can't I'm you are'

why cant Im you are

[root@localhost tmp]# echo "why can't I'm you are"

why can't I'm you are

命令替换

将命令执行的标准输出替换该命令所在的位置

反引号(``)和$()

$()命令可以嵌套

$()将\就是\,而反引号(``)将\解释为空格

利用反引号可以将其它语言执行的结果赋值给shell变量,从而用shell处理

例:

[root@localhost tmp]# echo \\

\

[root@localhost tmp]# echo $(echo \\)

\

[root@localhost 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"        #双引号有防止变量变分隔符的作用,保留变量分隔符

[root@localhost tmp]# ./a3.sh 

()\{}$"

()\{}$"

() {}$"

()\{}$"

2.

2.1

[root@localhost tmp]# echo \

> hello world

hello world

2.2

[root@localhost tmp]# echo \     #echo可以用""也可以不用

> "hello world"

hello world

2.3

[root@localhost tmp]# echo "\"   #注意这和前面两个存在本质的区别,这里的\转义了"导致缺少后",补全命令才结束,和2.4同

> hello world"

"

hello world

2.4

[root@localhost tmp]# echo "

> hello

> world"

hello

world

2.5

[root@localhost tmp]# variable=\

> hello world

bash: world: command not found         #变量赋值如果有空格必须用引号

2.6

[root@localhost tmp]# variable=\

> "hello world"

[root@localhost tmp]# echo $variable

hello world

2.7

[root@localhost tmp]# cat a5.sh 

#! /bin/bash

echo \                                                   #单个/在shell脚本中同样适用

hello world

[root@localhost tmp]# ./a5.sh

hello world

3.

\后跟字母的特殊含义:

\n 新的一行

\r 返回

\t tab键

\v或\f 换行但光标忍停留在原来的位置(横坐标相同)

\b 退格键

\a 发出警报声

\0xx ASCII码0xx对应的字符

例:

[root@localhost tmp]# echo hello\b\101

hellob101

[root@localhost tmp]# echo $'hello\b\101'        #和-e ""基本等价

hellA

[root@localhost tmp]# echo -e "hello\b\0101"    #注意\0101的0,没有0不能解析成ASCII码

hellA

[root@localhost tmp]# echo -e "hello\b\101"

hell\101

[root@localhost tmp]# echo -e hello\b\101        #注意-e没有""同样不能解析

hellob101

注意:

echo [选项] [字符串]

选项-e表示将转移符(\)后跟字符形成的特殊字符解释成特殊意义

选项-n表示输出文字后不换行:

[root@localhost tmp]# echo -n "hello"

hello[root@localhost tmp]#