之前做了很多跟 shell 有關的筆記,但那時候還沒有很好的筆記習慣(其實現在也沒有?),導致筆記散落各地,希望之後可以慢慢整理起來,變數這篇就當作系列的第一篇吧!
變數
變數主要分成 Environment variables 跟 shell variable
環境變數就是整個系統通用,需要去 export
shell variable 只存在當下這個 shell
常用指令
env
可以列出所有的環境變數
printenv
可以列出所有指定環境變數 ex printenv HOME
set
如果後面沒有接參數,會印出目前所有變數,包括環境變數,還有 shell function
unset
取消一般變數跟環境變數
export
把變數 export 出去代表變成環境變數
Assign 變數用法
- 等號兩邊不能直接接空白字元
- 變數名稱只能是英文字母與數字,但是開頭字元不能是數字
- 變數要存字串的話,雙引號裡面可以使用
$
轉換變數,但單引號不行
1 | 『var="lang is $LANG"』則『echo $var』可得『lang is zh_TW.UTF-8』 |
- 如果需要把指令得到的資訊存到變數中,可以使用反引號或者 $ 來存指令
1 | list=`ls` |
- 可以利用
declare
跟typeset
宣告變數類型
1 | -a :將後面名為 variable 的變數定義成為陣列 (array) 類型 |
1 | > sum=100+2 |
特殊變數
PS1
命令提示字元存在 PS1 這個變數裡面,指的就是 terminal 裡面左邊那邊要顯示什麼,如果要改的話就像下面這樣
1 | > cd /home |
錢字號 $
其實 $
本身也是個變數,代表目前這個 Shell 的執行緒代號,所以使用 echo $$
就可以看到現在這個 bash 的 PID
?
?
這個變數代表上一個指令的回傳值,如果沒有錯誤的話,回傳值就是 0
1 | > name="qoo" |
更多範例:
1 | > id -un |
1 | # Display the user name |
#
#
是一個特殊變數 表示輸入幾個參數
1 | # luser-demo06.sh |
1 | > ./luser-demo06.sh hello |
@
所有引數(每個都作為獨立的字串)
1 | for USER_NAME in "${@}" |
$*
所有的引數(合起來作為單個字串)
$!
最近一次執行的 background job PID
${RANDOM}
隨機產生一組數字
HOSTNAME
host name
查詢特殊變數
其實以上這些變數可以透過 man bash 查詢 Special Paramter
找到
$0
代表第0個參數,比方說 ./deploy.sh -e ...
裡面的 ./deploy.sh
$1
代表第一個參數以此類推
$#
代表參數的數量
$@
代表"$1" "$2" "$3" "$4"
之意,每個變數是獨立的
$*
代表"$1c$2c$3c$4"
這裡的 c 是分隔字元,預設是空白鍵,要注意跟 $@
還是有差別,但是一般來說記憶 $@
就可以
範例:
1 | # test.sh |
positional parameter
positional parameter 代表的是 command line 裡面的內容,像是 0
在 shell 裡面也是一個變數
parameter 是使用在 shell script 裡面的變數
argument 是傳進去 shell script 裡面的 data
兩者的關係是: argument 被寫在 command line 上面,然後變成存在 parameter 裡面的值
${0}
這個變數就代表第一個 position paramter,也就是使用者打在 command line 上面的 script 本身
1 | # luser-demo06.sh |
特殊操作子
目前在看 shell script 的時候主要看過三個類別比較特別的運算子:1.預設值 2.取字串的第幾個字 3.刪除取代替換文字
以下稍微整理一下:
預設值
:-
跟 -
語法差在有沒有冒號:
<變數>=${<要測試的變數>-<預設值>}
,反正就是預設值放在 -
後面
<變數>=${<要測試的變數>:-<預設值>}
,反正就是預設值放在 :-
後面
範例:
1 | > VARIABLE=${TEST:-app} |
兩者的行為表現上有差別,在上面的例子裡面,如果 TEST 這個變數有設定,但是值是 NULL 的話 :-
這種還是會取代掉,但 -
這種就不會有作用
例子:
1 | > TEST= |
:=
意思跟上面的很像,但如果用等於的話,連TEST 的值都會被替換掉
1 | > VARIABLE=${TEST:-app} |
:?
跟 ?
使用方式:
1 | USERNAME=${1:?"Specify a username"} |
兩者的差別:
${parameter:?word}
如果 parameter 沒有設定或是值是 nil, ‘’(空字串)的時候會跳出錯誤(把後面的訊息 print 到 STDERROR), 如果不是 interactive shell 的話會會 exit 這個 process
${parameter?word}
如果 parameter 沒有設定會跳出錯誤
1 | > unset xyzzy ; export plugh= |
cheat sheet:
cheat sheet 中文版:
取字串的第幾個字
用法:
1 | # ${parameter:offset:length} |
範例:
1 | for file in $(ls 2015*); do |
刪除取代替換文字
#
井字號的使用:從左邊刪除
1 | > path=${PATH} |
說明:
#
代表從變數內容的最前面開始向右刪除,且僅刪除最短的那個
##
代表從變數內容的最前面開始向右刪除,且僅刪除最長的那個
*
是萬用字元,代表0到無窮多個字元
%
的使用:從右邊刪除
1 | > echo ${path} |
取代:
1 | > echo ${path} |
cheat sheet