Shell是系統的用戶界面,提供了用戶與內核進行交互操作的一種介面。它接收用戶輸入的命令並把它送入內核去執行。實際上Shell是一個命令解釋器,它解釋由用戶輸入的命令並且把它們送到內核。 1 、Shell中的特殊符號 1.1 $ 美元符號。用來表示變數的值。如變數NAME的值為Mike,則使用$NA ...
Shell是系統的用戶界面,提供了用戶與內核進行交互操作的一種介面。它接收用戶輸入的命令並把它送入內核去執行。實際上Shell是一個命令解釋器,它解釋由用戶輸入的命令並且把它們送到內核。
1 、Shell中的特殊符號
1.1 $ 美元符號。用來表示變數的值。如變數NAME的值為Mike,則使用$NAME就可以得到“Mike”這個值。
1.2 # 井號。除了做為超級用戶的提示符之外,還可以在腳本中做為註釋的開頭字母,每一行語句中,從#號開始的部分就不執行了。
1.3 “” 雙引號。shell不會將一對雙引號之間的文本中的大多數特殊字元進行解釋,如#不再是註釋的開頭,它只表示一個井號“#”。但$仍然保持特殊含義。(在雙引號中的$加變數名,即:$PARAM_NAME,依然會轉換成變數的值。)
1.3.1 雙引號對於某些特殊符號是不起作用的, 例如:”,$,\,`(反引號)
1.3.2 雙引號和單引號不能嵌套。即:echo ‘””’ 輸出””, echo “’’” 輸出’’
1.4 ‘’ 單引號。shell不會將一對單引號之間的任何字元做特殊解釋。(在雙引號中的$加變數名,即:$PARAM_NAME,不會轉換成變數的值。)
1.4.1 echo “$HOME” (結果:/home/xiongguoan)
1.5 `` 倒引號。命令替換。在倒引號內部的shell命令首先被執行,其結果輸出代替用倒引號括起來的文本,不過特殊字元會被shell解釋。
1.5.1 echo ‘$HOME’ (結果:$HOME)
1.6 \ 斜杠。用來去掉在shell解釋中字元的特殊含義。在文本中,跟在\後面的一個字元不會被shell特殊解釋,但其餘的不受影響。
1.7 []中括弧, 主要是用來測試條件的,通常放在if語句的後面。 (不過還是不太明白),但是中括弧本身不會在測試語句執行後消失。
1.7.1 echo [$HOME] (結果:出現錯誤)
1.7.2 echo [$HOME ] (結果:[/home/xiongguoan ]) (註意:HOME後面有空格哦。)
1.7.3 echo [$HOME –eq ‘/xiong’] (結果:[/home/xiongguoan –eq /xiong])
1.8 {}大括弧,主要是和$符號配合,作為字元串連接來使用
1.8.1 echo ${HOME}ismydir (結果:/home/xiongguoanismydir)
2、 預定義的變數
2.1 特殊變數
$ shell變數名的開始,如$var | 管道,將標準輸出轉到下一個命令的標準輸入 $# 記錄傳遞給Shell的自變數個數 # 註釋開始 & 在後臺執行一個進程
? 匹配一個字元 * 匹配0到多個字元(與DOS不同,可在文件名中間使用,並且含.) $- 使用set及執行時傳遞給shell的標誌位 $! 最後一個子進程的進程號 $? 取最近一次命令執行後的退出狀態(返回碼) $* 傳遞給shell script的參數 $@ 所有參數,個別的用雙引號括起來 $0 當前shell的名字 $n (n:1-) 位置參數 $$ 進程標識號(Process Identifier Number, PID) > 輸出重定向 < 輸入重定向 >> 輸出重定向(追加方式) [] 列出字元變化範圍,如[a-z]
2.2 代值變數
* 任意字元串 ? 一個任意字元 [abc] a, b, c三者中之一 [a-n] 從a到n的任一字元
2.3 特殊字元的表達
\b 退回
\c 列印一行時沒有換行符 這個我們經常會用到
\f 換頁
\r 回車
\t 製表
\v 垂直製表
\\ 反斜線本身
2.4 其他字元
2.4.1 分號 ; 表示一行結束
2.4.2 圓括弧 () 表示在新的子shell中執行括弧內的命令(這樣可以不改變當前shell的狀態。)但是圓括弧在單/雙引號內失去作用,只作為普通字元。
2.4.3 花括弧
2.4.3.1 分割命令的用法
與圓括弧相似,但是:1. 花括弧內的命令在當前shell中執行;2.花括弧必須作為命令的第一個字元出現。
2.4.3.2 引用變數的用法
在$後面,表示變數名的開始和結束
2.4.4 方括弧
相當與test命令,用來執行測試條件,通常用在需要判斷條件的語句後面,例如:if,while等等。
3、設置變數
3.1 格式:VARNAME=value (i.e. PARAM=’hello’)
3.2 註意:等號的前後不能有空格。如果變數的值是一個命令的執行結果,請加上反引號(`)。
4、引用變數
4.1 $VARNAME
4.1.1 e.i. echo $HOME (結果:/home/xiongguoan)
4.2 變數預設值
4.2.1 在引用一個變數的時候可以設定預設值。如果在此之前,該變數已經設定了值,則此預設值無效。如果此時變數沒有被設定值,則使用此預設值(但是沒有改變此變數的值)。
4.2.2 echo Hello ${UNAME:-there} #其中there是UNAME的預設值
4.2.3 其他關於預設值與判讀變數的方法:
利用大括弧表示變數替換
表示形式 |
說明 |
${VARIABLE} |
基本變數替換。大括弧限定變數名的開始和結束 |
${VARIABLE:-DEFAULT} |
如果VARIABLE沒有值,則這種表示形式返回DEFAULT的值 |
${VARIABLE:=DEFAULT} |
如果VARIABLE沒有值,則這種表達形式返回DEFAULT的值。另外,如果VARIABLE沒有設置,則把DEFAULT的值賦予它 |
${VARIABLE:+VALUE} |
如果VARIABLE被設置,則這種表示形式返回VALUE;否則,返回一個空串 |
${# VARIABLE} |
這種表示形式返回VARIABLE值的長度,除非VARIABLE是* 或者@在為*或者@的特殊情況下,則返回$@所表示的元素的個數。要記住,$ @保存傳給該腳本的參數清單 |
${VARIABLE:?MESSAGE} |
如果VARIABLE沒有值,則這種表示形式返回MESSAGE的值。Shell也顯示出VARIABLE的名字,所以這種形式對捕獲得錯誤很有用 |
註意: 使用${VALIABLE:?MESSAGE},如果發現此變數此時沒有值,則腳本停止運行並顯示行號和變數名稱。 主要用於調試。
5、位置變數
5.1 使用$1,$2,$3…$9,${10},${11}…來代表輸入的參數。其中$0代表被執行的命令或者腳本的名字。$1,$2…代表輸入的第1,2…個參數
5.2 例子:
# cat count.sh#!/bin/sh
A=$1 # 將位置$1的數值讀入,並賦給變數A
B=$2 # 將位置$2的數值讀入,並賦給變數B
C=$[$A+$B] # 將變數A與B的值相加,將結果賦給C
echo $C # 顯示C的數值
結果:
# ./count.sh 3 6
9
# ./count.sh 34 28
62
5.3 $@和$*代表參數的列表,$#代表參數的數量 (不知道$@和$*之間的差別)
6、運算符和優先順序
Shell運算符和它們的優先順序順序
級別 |
運算符 |
說明 |
13 |
-, + |
單目負、單目正 |
12 |
!, ~ |
邏輯非、按位取反或補碼 |
11 |
* , / , % |
乘、除、取模 |
10 |
+, - |
加、減 |
9 |
<< , >> |
按位左移、按位右移 |
8 |
< =, > =, < , > |
小於或等於、大於或等於、小於、大於 |
7 |
= = , ! = |
等於、不等於 |
6 |
& |
按位與 |
5 |
^ |
按位異或 |
4 |
| |
按位或 |
3 |
&& |
邏輯與 |
2 |
| | |
邏輯或 |
1 |
=, + =, - =, * =, /=, % =, & =, ^ =, | =, << =, >> = |
賦值、運算且賦值 |
7、source / export / let / unset
7.1 source
7.1.1 正常情況下,腳本中執行的參數設置只能影響到shell腳本本身的執行環境,不能影響到調用此shell的腳本。
7.1.2 使用source命令執行腳本,可以讓腳本影響到父shell的環境(即調用此shell的當前shell)。
7.1.3 例如:source env.sh
7.2 export
7.2.1 在bash下,使用export建立環境變數後,會影響到子shell腳本和當前shell的環境變數
7.3 unset
7.3.1 刪除環境變數
7.3.2 i.e.
#export newval=1
#echo $newval
1
#unset newval
#echo $newval
(ß此處為空行,newval已經被刪除)
7.4 let
7.4.1 在bash中只用此命令可以建立一個臨時的變數,此變數不會影響到子shell
8、邏輯判斷
8.1 if
8.1.1 單格式與嵌套
if 條件表達式 ;then #當條件為真時執行以下語句 命令列表 else #為假時執行以下語句 命令列表 fi
if 語句也可以嵌套使用
if 條件表達式1;then if 條件表達式2;then 命令列表 else if 條件表達式3;then 命令列表 else 命令列表 fi fi else 命令列表 fi
8.1.2 多分支格式
if test -f "$1" ;then lpr $1 elif test -d "$1" ;then (cd $1;lpr $1) else echo "$1不是文件或目錄" fi
8.2 case
8.2.1 格式
case $newval in
1) #這裡是可能值1
echo 1
;; #表示第一個分支結束
2) #這裡是可能值 2
echo 2
;; #第二個分支結束
*) #表示其他可能值,必須在最後,否則他後面的語句無法執行
echo unkown
esac #case 語句結束
8.3 while /until
格式:
while 表達式 do 命令列表 done
例如:
Sum=0 i=0 while true #true是系統的關鍵詞 表示真 do i=`expr $i + 1` Sum=`expr $Sum + $i` if [ $i = "100" ] then break; fi done echo $i $Sum
最後這個程式顯示的是 100 5050
下麵將這個程式再改動一下
Sum=0 i=0 while [ $i != "100" ] do i=`expr $i + 1` Sum=`expr $Sum + $i` done echo $i $Sum
改動後的程式運算結果和上面是一樣 但程式比上面的要簡練
在這個迴圈中還可以以until做為測試條件 它正好與while測試的條件相反,也就是當條件為假時將繼續執行迴圈體內的語句,否則就退出迴圈體,下麵還用這個例子.
Sum=0 i=0 until [ $i = "100" ] do i=`expr $i + 1` Sum=`expr $Sum + $i` done echo $i $Sum
當i不等於100時迴圈 就是當條件為假時迴圈,否則就退出,而第一個例子是當i不等於100 時迴圈,也就是測試條件為真時迴圈.
8.4 for
8.4.1 枚舉用法
8.4.1.1 格式
for 變數 in 名字列表 do 命令列表 done
8.4.1.2 格式
for n in {1..10} do echo $n done
for letter in a b c d e; do echo $letter done
8.4.2 文件用法
8.4.2.1 格式
for file in * do echo $file done
例子
for File in a1 a2 a3 a4 a5 do diff aa/$File bb/$File done
8.4.3 累加格式
for (( i=1;$i<10;i++)) do echo $i done
for(( i=1;$i<10;i=$[$i+1’ ]) do echo $i done
8.5 其他迴圈控制語句
break 命令不執行當前迴圈體內break下麵的語句從當前迴圈退出.
continue 命令是程式在本循體內忽略下麵的語句,從迴圈頭開始執行.
8.6 邏輯判斷的表達
一、判斷文件的屬性
格式:-操作符 filename
-e 文件存在返回1, 否則返回0 -r 文件可讀返回1,否則返回0 -w 文件可寫返回1,否則返回0 -x 文件可執行返回1,否則返回0 -o 文件屬於用戶本人返回1, 否則返回0 -z 文件長度為0返回1, 否則返回0. -f 文件為普通文件返回1, 否則返回0 -d 文件為目錄文件時返回1, 否則返回0
二、測試字元串
字元串1 = 字元串2 當兩個字串相等時為真 字元串1 != 字元串2 當兩個字串不等時為真 -n 字元串 當字元串的長度大於0時為真 -z 字元串 當字元串的長度為0時為真 字元串 當串字元串為非空時為真
三、測試兩個整數關係
數字1 -eq 數字2 兩數相等為真 數字1 -ne 數字2 兩數不等為真 數字1 -gt 數字2 數字1大於數字2為真 數字1 -ge 數字2 數字1大於等於數字2為真 數字1 -lt 數字2 數字1小於數字2為真 數字1 -le 數字2 數字1小於等於數字2為真
四、邏輯測試
-a 與 -o 或 ! 非
9、shell中的表達式
9.1 shell 輸出重定向
9.1.1 管道 |
就管道符前的命令的輸出作為管道符後的命令的輸入。
ls | grep ‘.txt’
將ls的輸出作為grep 的輸入。 grep從輸入中找出所有包含.txt的行。
9.1.2 輸出 >
將右尖括弧前的命令的輸入重定向到尖括弧後的文件中。
例如:
ls *.sh > list.txt
將當前目錄下所有末尾名為sh的文件的列表寫入到list.txt
9.1.3 輸入 <
將左箭頭後面的文件作為左箭頭前的命令的輸入。
例如:
grep “a” < test.sh
將test.sh中找到所有包含a的行
9.1.4 錯誤輸出重定向
預設bash有3個標準輸入輸出設備。
0 標準輸入
1 標準輸出
2錯誤輸出
如果執行腳本的時候發生錯誤,會輸出到2上。
要想就將錯誤的輸出也輸出在標準輸出上,需要重定向。
例如:
./test.sh > a.log 2>&1
後面2>&1就是將標準錯誤的輸出重定向到標準輸出上。
9.2 tee
9.2.1 將此命令的輸入分叉,一支輸出到屏幕一支可以重定向到其他位置。
例如: ./test.sh | tee >a.txt 2>&1
運行test.sh,通過tee輸出到a.txt,同時屏幕上可以看到輸出。並且將錯誤輸出重定向到標準輸出( 2>&1 )
9.3 cpio
9.3.1 文件或目錄打包
9.3.1.1 含子目錄打包
find . -name '*.sh' | cpio -o > shell.cpio
將當前目錄及其子目錄下的sh文件打包成一個文件庫為shell.cpio。
9.3.1.2 不含子目錄的打包
ls *.sh | cpio -o > shell.cpio
將當前目錄下的sh文件(不含子目錄)打包成一個文件庫為shell.cpio。
9.3.2 壓縮
文件打包完成後,即可用Unix中的compress命令(/usr/bin下)壓縮打包文件。對一般的文本文件,壓縮率較高,可達81%。
例如:compress shell.cpio則將文件庫壓縮為shell.cpio.Z(自動添加.Z並刪除shell.cpio )。
9.3.3 解壓
uncompress shell.cpio.Z則自動還原為shell.cpio。
9.3.4 解包展開
將按原目錄結構解包展開到當前所在目錄下。若以相對路徑打包的,當解包展開時,也是以相對路徑存放展開的文件數據;若以絕對路徑打包的,當解包展開時,也是以絕對路徑存放展開的文件數據。因此註意若為相對路徑,應先進入相應的目錄下再展開。
cd /u1
cpio –id < shell.cpio 解壓到當期目錄。
cpio –iud < shell.cpio則文件若存在將被覆蓋,即強制覆蓋。
cpio –id < shell.cpio env.sh 解壓縮env.sh
9.3.5 顯示包內的文件
cpio –it < shell.cpio
9.4 exec
9.4.1 將此命令後的參數作為命令在當前的shell中執行,當前的shell或者腳本不在執行。
例如: exec ls
當前進程替換為ls,執行結束後就退出了。
例如:在a.sh 中包含
exec b.sh 則當a.sh 執行到此句後,被b.sh替換,a.sh中此句後的語句不會再被執行。
9.5 fork
9.5.1 將此命令的參數,新建一個進程來執行
例如:在a.sh 中包含
fork b.sh 則當a.sh 執行到此句後,被b.sh替換,a.sh中此句後的語句繼續執行。b.sh在新的進程中同時執行。
9.6 expr
9.6.1 expr argument operator argument
9.6.2 一般用於整數的運算。 例如:
#set newval=1
#echo $newval
1
#set newval=`expr $newval + 1`
#echo $newval
2
#set newval=$newval+1
#echo $newval
2+1
9.7 test
9.7.1 測試,通常用在需要判斷的語句後面,例如:if,while,等等。
9.7.2 很多時候可以和中括弧[]互換,我不知道區別是什麼。
9.7.3 例子:
i=1 if test”$ i” == “1” then echo true else echo false fi
9.8 exit
退出當前的shell,執行結果可以在shell中用$?查看
例如:exit 2
9.9 read
從標準輸入讀取數據。
例:
$ read var1 var2 var3 Hello my friends $ echo $var1 $var2 $var3 Hello my friends $ echo $var1 Hello
9.10 shift
9.10.1 每次調用的時候,將參數列表中的第一個參數去掉。這樣可以迴圈得到第一個參數。
9.10.2 例子:
cat t.sh sum=0 until [ $# -eq 0 ] do echo $* sum=`expr $sum + $1` shift done echo result is: $sum #./t.sh 1 2 3 1 2 3 2 3 3
11、附件:Linux 易被遺漏的命令解析
11.1 grep
11.1.1 grep ‘string’ filename
11.1.1.1e.i.: grep ‘list’ mytxt.txt 在mytxt.txt中尋找包含list字元串的所有行
11.1.2 “-v” : 相反的。 即不包含字元串。
11.1.2.1e.i.: grep –v ‘list’ mytxt.txt
11.1.3 cat mytxt | grep ‘list’
將cat mytxt作為源, 從中查找包含list字元串的行
11.2 find
11.2.1 -atime n : 指查找系統中最後n*24小時訪問的文件;
11.2.2 -ctime n : 指查找系統中最後n*24小時被改變狀態的文件;
11.2.3 -mtime n : 指查找系統中最後n*24小時被修改的文件。
11.2.4 在當前目錄下(包含子目錄),查找所有txt文件並找出含有字元串"bin"的行
find ./ -name "*.txt" -exec grep "bin" {} \;
11.2.5 在當前目錄下(包含子目錄),刪除所有txt文件
find ./ -name "*.txt" -exec rm {} \;
11.3 du
11.3.1 顯示文件的大小
11.3.2 i.e.
#du *.txt
1230 myfile1.txt
456 myfile2.txt
11.4 awk
11.4.1 提取輸入中的某個參數
11.4.2 提取輸入中每一行的第一個參數
#echo `du *.txt | awk ‘{print $1}’`
1230 456
提取子字元串
#echo `du *.bin | awk '{print substr($1,2,3)}'`
11.5 前後臺運行
11.5.1 將某個程式在後臺啟動起來,只需要在命令的最後加上 & 符號。
例如: ./test.sh &
11.5.2 將當前正在運行的程式切換到後臺
11.5.2.1 當按下^z的時候,當前的應用程式就會切換到後臺,但是此時的狀態是停止的狀態。
11.5.2.2 使用jobs命令可以看到當前在後臺運行的程式的列表。
例如:jobs
[1]+ stopped top
[2]+stopped find | grep *.txt > a.log
11.5.2.3 使用bg命令可以將某個後臺程式繼續運行。
#bg %2
#jobs
[1]+ stopped top
[2]+ Running find | grep *.txt > a.log
11.5.3 將後臺運行的程式切回到前臺
#fg %2
將find 命令切回到前臺
11.6 shell的執行選項
-n 測試shell script語法結構,只讀取shell script但不執行 -x 進入跟蹤方式,顯示所執行的每一條命令,用於調度 -a Tag all variables for export -c "string" 從strings中讀取命令 -e 非交互方式 -f 關閉shell文件名產生功能 -h locate and remember functions as defind -i 交互方式 -k 從環境變數中讀取命令的參數 -r 限制方式 -s 從標準輸入讀取命令 -t 執行命令後退出(shell exits) -u 在替換中如使用未定義變數為錯誤 -v verbose,顯示shell輸入行
11.7 alias
建立別名
alias dir ls
11.8 xargs
執行本命令的第一個參數,並將xargs的輸入作為被執行命令的參數
例如:
find . -name '*.c' | xargs cat
將本目錄及其子目錄下所有的C文件使用cat命令顯示其內容。
12、附件:Bash中影響環境變數的命令
Shell有若幹以變數為工作對象的命令,其中有些命令似乎重覆了。例如,可以用declare、export和typeset命令來創建全局(或轉出)的變數。typeset命令是declare的同義詞。
Declare 命令
語法:declare [options] [name [= value]]
摘要:用於顯示或設置變數。
declare命令使用四個選項:
-f 只顯示函數名 -r 創建只讀變數。只讀變數不能被賦予新值或取消設置,除非使用declare或者typeset命令 -x 創建轉出(exported)變數 -i 創建整數變數。如果我們想給一個整數變數賦予文本值,實際上是賦予0使用+ 代替-,可以顛倒選項的含義。
如果沒有使用參數,則declare顯示當前已定義變數和函數的列表。讓我們關註一下-r選項:
$ declare –r title=" paradise Lost"
$ title = " Xenogenesis"
bash: title: read-only variable
$ declare title= " Xenogenesis"
$ echo $title
Xecogenesis
$ typeset title = " The Longing Ring”
$ echo $title
The Longing Ring
這個示例表明,只有declare或typeset命令可以修改只讀變數的值。
export命令
語法:export [options] [name [= value]]
摘要:用於創建傳給子Shell的變數。
export命令使用四個選項:
-- 表明選項結束。所有後續參數都是實參 -f 表明在“名-值”對中的名字是函數名 -n 把全局變數轉換成局部變數。換句話說,命名的變數不再傳給子Shell -p 顯示全局變數列表
如果沒有用參數,則假定是一個-p參數,並且顯示出全局變數的列表:
$ export
declare –x ENV = "/home/medined/ . bashrc"
declare –x HISTFILESIZE = "1000"
…
declare –xi numPages = "314"
declare –xr title = "The Longing Ring"
declare –xri numChapters = "32"
這種顯示的一個有趣的特性是,它告訴我們哪些變數只能是整數、是只讀的,或者二者皆可。
let命令
語法:let expression
摘要:用於求整數表達式的值。
let命令計算整數表達式的值。它通常用來增加計數器變數的值,如例5-9所示。
例5-9 let——使用let命令
# ! /bin/bash
count=1
for element in $@
do
echo " $element is element $count"
let count+=1
done
下麵是這個腳本運行結果示例:
$ chmod + x let
$ . /let one two three
one is element 1
two is element 2
three is element 3
註意:如果我們習慣在表達式中使用空格,那麼要用雙引號把表達式括起來,如:
let "count + =1"
否則會導致語句錯誤。
local 命令
語法:local [name [= value]]
摘要:用於創建不能傳給子Shell的變數。這個命令僅在過程內部有效。
簡單說來,local命令創建的變數不能被子Shell存取。因此,只能在函數內部使用local命令。我們可以在命令行或腳本中使用“變數=值”這種形式的賦值命令。如果使用local時不帶實參,那麼當前已定義的局部變數列表就送往標準輸出顯示。
readonly命令
語法:readonly [options] [name[ = value]]
摘要:用於顯示或者設置只讀變數。
Readonly命令使用兩個選項:
-- 表明選項結束。所有後續參數都是實參
-f 創建只讀函數
如果沒有用參數,則readonly顯示當前已定義的只讀變數和函數的列表。
set命令
語法:set [--abefhkmnptuvxidCHP] [-o option] [name [= value]]
摘要:用於設置或者重置各種Shell選項。
set 命令可實現很多不同的功能——並非其中所有的功能都與變數有關。由於本節的其他命令重覆了通過set命令可用的那些變數選項,所以這裡對set命令不做詳細說明。
shift命令
語法:shift [n]
摘要:用於移動位置變數。
shift命令調整位置變數,使$3的值賦予$2,而$2的值賦予$1。當執行shift命令時,這種波動作用影響到所定義的各個位置變數。往往使用shift命令來檢查過程參數的特定值——如為選項設置標誌變數時。
typeset命令
語法:typeset [options] [name [= value]]
摘要:用於顯示或者設置變數。
typeset 命令是declare命令的同義詞。
unset命令
語法:unset [options] name [name …]
摘要:用於取消變數定義。
unset命令使用兩個選項:
-- 表明選項結束,所有後續參數都是實參
-f 創建只讀函數
unset命令從Shell環境中刪除指定的變數和函數。註意,不能取消對PATH、IFS、PPID、PS1、PS2、UID和EUID的設置。如果我們取消RANDOM、SECONDS、LINENO或HISTCMD等變數的設置,它們就失去特有屬性。
註:原文shell鏈接 http://www.cnblogs.com/chen-lhx/p/5743438.html
註:系統學習鏈接 http://shellbaike.com/