第六章 shell學習之變量和引用

變量

本地變量:類似於局部變量,只在當前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]# 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章