shell--變量的替換


變量是什麼,變量是腳本編程中進行數據表現的一種方法,說白了,變量不過是計算機爲了保留數據項,而在內存中分配的一個位置或一組位置的標識或名字。

變量的替換

變量的名字就是保存變量值的地方,引用變量的值就叫做變量替換

$

shell中要仔細區分變量的名字和變量的值,如果a是一個變量,那麼$a就是引用這個變量的值,即變量所包含的數據。

andrew@andrew-Thurley:/work/linux-sys/bash$a=1
andrew@andrew-Thurley:/work/linux-sys/bash$ echo a 
a
andrew@andrew-Thurley:/work/linux-sys/bash$ echo $a
1

當變量裸體出現的時候,也就是說沒有$前綴的時候,那麼變量可能存在如下幾種情況

  1. 變量被聲明或被賦值
  2. 變量被unset
  3. 變量被exporte
  4. 或者處在一種特殊的情況下,變量代表一種信號

trap.sh

#!/bin/bash
# 使用trap來捕捉變量值.

trap 'echo Variable Listing --- a = $a b = $b' EXIT
# EXIT是腳本中exit命令所產生信號的名字.
#
# "trap"所指定的命令並不會馬上執行,
#+ 只有接收到合適的信號, 這些命令纔會執行.
echo "This prints before the \"trap\" --"
echo "even though the script sees the \"trap\" first."
echo
a=39
b=36
exit 0
andrew@andrew-Thurley:/work/linux-sys/bash/2.基本/src$ bash trap.sh 
This prints before the "trap" --
even though the script sees the "trap" first.

Variable Listing --- a = 39 b = 36

被一雙引號""括起來的變量替換是不會被阻止的,所以雙引號被稱爲部分引用,有的時候又被稱爲弱引用。如果是使用單引號的話''那麼比變量的替換就會被禁止,變量名只會被解釋成字面的意思,不會出發變量的替換。所以單引號被稱爲全引用,有的時候被稱爲強引用

#!/bin/bash

# 變量賦值和替換

a=375
hello=$a

#------------------------------------------------------------------
# 強烈注意, 在賦值的的時候, 等號前後一定不要有空格.
# 如果出現空格會怎麼樣?
 
# "VARIABLE =value"
#
#% 腳本將嘗試運行一個"VARIABLE"的命令, 帶着一個"=value"參數.

# "VARIABLE= value"
#
#% 腳本將嘗試運行一個"value"的命令,
#+ 並且帶着一個被賦值成""的環境變量"VARIABLE".
#------------------------------------------------------------------
echo hello
# 沒有變量引用, 只是個hello字符串.
echo $hello
echo ${hello} # 同上.

echo "$hello"
echo "${hello}"

echo

hello="A B C D"
echo $hello
# A B C D
echo "$hello" # A B C D
# 就象你看到的echo $hello和echo "$hello"將給出不同的結果.
# ===============================================================
# 引用一個變量將保留其中的空白, 當然, 如果是變量替換就不會保留了.
# ===============================================================

echo

echo '$hello' # $hello
#
# 全引用的作用將會導致"$"被解釋爲單獨的字符,
#+ 而不是變量前綴.

# 注意這兩種引用所產生的不同的效果.

# 設置爲空值.
hello=    

echo "\$hello (null value) = $hello"
# 注意設置一個變量爲null, 與unset這個變量, 並不是一回事
#+ 雖然最終的結果相同(具體見下邊).
 
# --------------------------------------------------------------

# 可以在同一行上設置多個變量,
#+ 但是必須以空白進行分隔.
# 慎用, 這麼做會降低可讀性, 並且不可移植.

var1=21 var2=22 var3=$V3
echo
echo "var1=$var1
var2=$var2
var3=$var3"
 
# 在老版本的"sh"上可能會引起問題.

# --------------------------------------------------------------

echo; echo

numbers="one two three"
#
other_numbers="1 2 3"
#

# 如果在變量中存在空白, If there is whitespace embedded within a variable,
#+ 那麼就必須加上引用.
# other_numbers=1 2 3
# 給出一個錯誤消息.
echo "numbers = $numbers"
echo "other_numbers = $other_numbers"
# other_numbers = 1 2 3
# 不過也可以採用將空白轉義的方法.
mixed_bag=2\ ---\ Whatever
#在轉義符後邊的空格(\).
 
echo "$mixed_bag"
# 2 --- Whatever

echo; echo

echo "uninitialized_variable = $uninitialized_variable"
# Uninitialized變量爲null(就是沒有值).
uninitialized_variable=
# 聲明, 但是沒有初始化這個變量,
 
#+ 其實和前邊設置爲空值的作用是一樣的.
echo "uninitialized_variable = $uninitialized_variable"
 
# 還是一個空值.
 
uninitialized_variable=23
# 賦值.
unset uninitialized_variable
# Unset這個變量.
echo "uninitialized_variable = $uninitialized_variable"
 
# 還是一個空值.
echo
 
exit 0

像C語言中的變量一樣,一個未初始化的變量將會是null值 - 就是未賦值(但並不代表值是0),在給變量 賦值之前就使用這個變量通常會引起問題。

小知識加油站–trap

trap的格式如下,功能就是捕捉信號,並對信號進行處理

trap [-lp] [[arg] sigspec ...]

trap使用官方簡介

  trap

  Automatically execute commands after receiving signals by processes or the operating system.
  Can be used to perform cleanups for interruptions by the user or other actions.

  - List available signals to set traps for:
    trap -l

  - List active traps for the current shell:
    trap -p

  - Set a trap to execute commands when one or more signals are detected:
    trap 'echo "Caught signal SIGHUP"' SIGHUP

  - Remove active traps:
    trap - SIGHUP SIGINT

  • arg可以是shell命令或者自定義函數
  • sigspec可以是以下的一個或多個
  • 定義在<signal.h>中的信號名或者數值。信號名的大小寫不敏感,SIG這個前綴也是可選的。以下的命令的效果都是一樣的
trap "echo SIGINT" SIGINT
trap "echo SIGINT" sigint
trap "echo SIGINT" 2
trap "echo SIGINT" int 
trap "echo SIGINT" Int

調試腳本時,trap經常用到的信號量

  • EXIT:在shell退出前執行trap設置的命令,也可以指定爲0
  • RETURN:在.和``source執行其他腳本返回時,執行trap`設置的命令
  • DEBUG:在任何命令執行前執行trap設置的命令,但對於函數僅在函數的第一條命令前執行一次
  • ERR:在命令結果爲非0時,執行trap設置的命令
#! /bin/bash
# 使用trap實現在每個函數開始之前打印以便打印,這樣就能準確的定位到函數的位置
# 從而實現對腳本的調試
trap "echo before a func is called" DEBUG
# 當. 或者 source 調用結束的時候出發
trap "echo . or source is called "  RETURN
func()
{

    echo "不管你信不信,這是一個函數"
    exit 0
}
# 測試
echo "call ."
. traptest

# 函數的調用
func
# DEBUG 查看調試信號是否有效的設置了
# trap -p RETURN
# trap -p DEBUG

exit 0

執行結果

andrew@andrew-Thurley:/work/linux-sys/bash/2.基本/src$ bash trap_func.sh 
before a func iis called
before a func iis called
call .
before a func iis called
. or source is called
before a func iis called
不管你信不信,這是一個函數
  • trap -l:列出所有信號的數值和名字,類似於kill -l
andrew@andrew-Thurley:~$ trap -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	
  • trap -p:列出通過trap設置過的信號處理命令
andrew@andrew-Thurley:~$ trap -p
trap -- 'name ' SIGINT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
trap -- 'name ' RETURN
trap "" sigspec :忽略sigspec指定的信號
trap "do something" sigspec:收到sigspec指定的信號時,do some thing後,繼續執行後續命令。
trap sigspec or trap - sigspec:恢復sigspec指定的信號的默認行爲

注意

  • 在函數中設置的trap也是全局生效的
#!/bin/bash
# trap設置在函數中的tap也是全局有效的
foo()
{    
    trap "echo func is called" DEBUG 
}

# 輸出 func is called
foo
# 調試觸發
#trap -p DEBUG
# 輸出trap -- 'echo func is called' SIGINT
exit 0
  • 對於同一個信號,只有最後一次trap生效
  • trap只在本進程內有效,它的子進程不會繼承trap的設置。

使用trap設計一個用於反應程序執行過程的腳本

#!/bin/bash
# 使用trap來捕捉變量值.

# EXIT代表在函數退出前,執行trap
trap 'echo Variable Listing --- ret=${ret}' EXIT

ps -A
if [ $? == 0 ];then
    echo "commond exec OK!"
    ret=0
else
    ret=1
fi

echo "注意這裏,還沒有調用trap"

# trap是在退出的時候清理程序時調用的
exit 0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章