Shell程式設計入門學習筆記之shell變數
shell簡介
Shell本身是一個用C語言編寫的程式,它是使用者使用Unix/Linux的橋樑,使用者的大部分工作都是通過Shell完成的。
他不是Unix/Linux系統核心的一部分,但是他呼叫了系統核心的大部分功能來執行程式、建立檔案並以並行的方式協調各個程式的執行。因此,對於使用者來說,shell是最重要的實用程式。
可以說,shell使用的熟練程度反映了使用者對Unix/Linux使用的熟練程度。
Shell的兩種執行命令的方式:
- 互動式:解釋執行使用者的命令,使用者輸入一條命令,Shell就解釋執行一條。
- 批處理:使用者事先寫一個Shell指令碼(Script),其中有很多條命令,讓Shell一次把這些命令執行完,而不必一條一條地敲命令。
Shell指令碼和程式語言很相似,也有變數和流程控制語句,但Shell指令碼是解釋執行的,不需要編譯,Shell程式從指令碼中一行一行讀取並執行這些命令,相當於一個使用者把指令碼中的命令一行一行敲到Shell提示符下執行。
幾種常見的Shell
Shell是一種指令碼語言,就必須有直譯器來執行這些指令碼。
Unix/Linux
上常見的Shell指令碼編譯器有bash
、sh
、csh
、ksh
等,習慣上把它們稱為一種Shell。我們常說有多少種Shell,其實說的是Shell指令碼直譯器。
bash
:是Linux標準預設的shell,內部命令一共有40種。
sh
:是Unix標準預設的shell。(bash完全相容sh,所以用sh寫的指令碼可以不加修改的在bahs中執行)。
ash
:是Linux中佔用系統資源最少的一個shell,只包含24個內部命令,因而使用起來不方便。
csh
:是Linux比較大的核心,共有52個內部命令。
第一個Shell指令碼
#!/bin/bash
echo "Hello World !"
#!
是一個約定的標記,它告訴系統這個指令碼需要什麼直譯器來執行,即使用哪一種Shell。
執行Shell指令碼有兩種方法
1、作為可執行程式
將上邊的程式碼儲存為test.sh
,並cd
到相應目錄:
chmod +x ./test.sh #給該指令碼增加可執行的許可權
./test.sh # 執行指令碼
注意:通過這種方式執行bash指令碼,第一行一定要寫對,好讓系統查詢到正確的直譯器。
2、作為直譯器引數
/bin/sh test.sh
/bin/php test.php
這種方式執行的指令碼,不需要在第一行指定直譯器資訊,寫了也沒用。
#!/bin/bash
# Author : JonnyYue
echo "What is your name?"
read PERSON
echo "Hello ,$PERSON"
chmod +x ./test.sh
$./test.sh
輸出:
What is your name?
mozhiyan
Hello, mozhiyan
Shell變數
定義變數
定義變數時,變數名不加美元符號。
變數名 = “value”
注意:變數名和等號之間不能有空格。
變數名的命名規則遵循如下規則:
- 首個字母必須有字母(a-z、A-Z)
- 中間不能有空格,可以使用下劃線(_)
- 不能使用標點符號。
- 不能使用
bash
裡的關鍵字
使用變數
使用一個已經定義過的變數,只需要在變數名前面加上美元符號$就可以了。
a="hello"
echo $a
echo ${a}
變數名後面的{}
是可選的,加不加都行,加花括號是為了幫助直譯器識別變數的邊界,比如下面這種情況:
${name}is a boy
如果不給name加上花括號,直譯器就會把nameis 當作一個變數。
重新定義變數
已定義的變數,可以被重新定義。
your_name="tom"
echo $your_name
your_name="alibaba" #不能加$
echo $your_name
只讀變數
#!/bin/bash
myUrl="http://www.google.com"
readonly myUrl
刪除變數
unset variable_name
變數被刪除後不能再次使用。unset 命令不能刪除只讀變數。
變數型別
有三種類型:
- 區域性變數
- 僅在當前shell例項中有效,其他shell啟動的程式不能訪問區域性變數
- 環境變數
- 所有的程式,包括shell啟動的程式,都能訪問環境變數,有些程式需要環境變數來保證其正常執行。必要的時候shell指令碼也可以定義環境變數。
- shell變數
- shell變數是由shell程式設定的特殊變數。shell變數中有一部分是環境變數,有一部分是區域性變數,這些變數保證了shell的正常執行。
特殊變數
變數 | 含義 |
---|---|
$0 |
當前指令碼的檔名 |
$n |
傳遞給指令碼或函式的引數。n是一個數字,表示第幾個引數。 |
$# |
傳遞給指令碼或函式的引數個數 |
$* |
傳遞給指令碼或函式的所有引數 |
[email protected] |
傳遞給指令碼或函式的所有引數 |
$? |
上個命令的退出狀態,或函式的返回值。 |
$$ |
當前Shell程序的ID。對於Shell指令碼,就是這些指令碼所在的程序ID |
命令列引數
執行指令碼時傳遞給指令碼的引數稱為命令列引數。
#!/bin/bash
echo "File Name: $0"
echo "First Parameter : $1"
echo "First Parameter : $2"
echo "Quoted Values: [email protected]"
echo "Quoted Values: $*"
echo "Total Number of Parameters : $#"
執行結果:
$./test.sh Zara Ali
File Name : ./test.sh
First Parameter : Zara
Second Parameter : Ali
Quoted Values: Zara Ali
Quoted Values: Zara Ali
Total Number of Parameters : 2
*和@的區別
∗
和@
都表示傳遞給函式或指令碼的所有引數,不被雙引號(" “)包含時,都以"1"“2” … “$n” 的形式輸出所有引數。
但是當它們被雙引號(” ")包含時,“∗"會將所有的引數作為一個整體,以"1 2…n"的形式輸出所有引數;”@“會將各個引數分開,以"1” “2”…“n” 的形式輸出所有引數。
下面的例子可以清楚的看到 ∗和@ 的區別:
#!/bin/bash
echo "\$*=" $*
echo "\"\$*\"=" "$*"
echo "\[email protected]=" [email protected]
echo "\"\[email protected]\"=" "[email protected]"
echo "print each param from \$*"
for var in $*
do
echo "$var"
done
echo "print each param from \[email protected]"
for var in [email protected]
do
echo "$var"
done
echo "print each param from \"\$*\""
for var in "$*"
do
echo "$var"
done
echo "print each param from \"\[email protected]\""
for var in "[email protected]"
do
echo "$var"
執行 ./test.sh "a" "b" "c" "d"
,看到下面的結果::
$*= a b c d
"$*"= a b c d
[email protected]= a b c d
"[email protected]"= a b c d
print each param from $*
a
b
c
d
print each param from [email protected]
a
b
c
d
print each param from "$*"
a b c d
print each param from "[email protected]"
a
b
c
d
退出狀態
$?
可以獲取上一個命令的退出狀態。所謂退出狀態,就是上一個命令執行後的返回結果。
退出狀態是一個數字,一般情況下,大部分命令執行成功會返回 0,失敗返回 1。
Shell 替換
如果表示式中包含特殊字元,Shell將會進行替換。比如轉義字元
下面的轉義字元都可以用在echo
中:
轉義字元 | 含義 |
---|---|
\\ |
反斜槓 |
\a |
警報,響鈴 |
\b |
退格(刪除鍵) |
\f |
換頁(FF),將當前位置移到下頁開頭 |
\n |
換行 |
\r |
回車 |
\t |
水平製表符(tab鍵) |
\v |
垂直製表符 |
可以使用echo -e
來禁止轉義,預設也是不轉義的。
命令替換
命令替換是指Shell可以先執行命令,將輸出結果暫時儲存,在適當的地方輸出。
命令替換的語法:
`command` # 注意是反引號,而不是單引號。
#!/bin/bash
DATE=`date`
echo "Date is $DATE"
USERS=`who | wc -l`
echo "Logged in user are $USERS"
UP=`date ; uptime`
echo "Uptime is $UP"
執行結果:
Date is Thu Jul 2 03:59:57 MST 2009
Logged in user are 1
Uptime is Thu Jul 2 03:59:57 MST 2009
03:59:57 up 20 days, 14:03, 1 user, load avg: 0.13, 0.07, 0.15
變數替換
變數替換可以根據變數的狀態(是否為空、是否定義等)來改變它的值。
可以使用的變數替換形式:
形式 | 說明 |
---|---|
${var} |
變數本來的值 |
${var:-word} |
如果變數 var 為空或已被刪除(unset),那麼返回 word,但不改變 var 的值。 |
${var:=word} |
如果變數 var 為空或已被刪除(unset),那麼返回 word,並將 var 的值設定為 word。 |
${var:?message} |
如果變數 var 為空或已被刪除(unset),那麼將訊息 message 送到標準錯誤輸出,可以用來檢測變數 var 是否可以被正常賦值。 若此替換出現在Shell指令碼中,那麼指令碼將停止執行。 |
${var:+word} |
如果變數 var 被定義,那麼返回 word,但不改變 var 的值。 |
#!/bin/bash
echo ${var:-"Variable is not set"}
echo "1 - Value of var is ${var}"
echo ${var:="Variable is not set"}
echo "2 - Value of var is ${var}"
unset var
echo ${var:+"This is default value"}
echo "3 - Value of var is $var"
var="Prefix"
echo ${var:+"This is default value"}
echo "4 - Value of var is $var"
echo ${var:?"Print this message"}
echo "5 - Value of var is ${var}"
執行結果:
Variable is not set
1 - Value of var is
Variable is not set
2 - Value of var is Variable is not set
3 - Value of var is
This is default value
4 - Value of var is Prefix
Prefix
5 - Value of var is Prefix