主要從以下幾個方面進行bash入門級的總結:
1、命令曆史、命令補全
2、管道、重新導向
3、命令別名和命令替換
4、命令列編輯
5、檔案名稱通配
6、Bash的相關設定檔及變數
7、編程(條件判斷、迴圈控制)
8、bash中的數組
9、shell編程技巧和編程規範
1、命令曆史、命令補全
查看命令曆史:history
-c:清空命令曆史
-d OFFSET [n]: 刪除指定位置的命令
-w:儲存命令曆史至曆史檔案中,這對於經常在不同的終端上執行命令很有用
命令曆史的提示:
!n:執行命令曆史中的第n條命令;
!-n:執行命令曆史中的倒數第n條命令;
!!: 執行上一條命令;
!string:執行命令曆史中最近一個以指定字串開頭的命令
!$:引用前一個命令的最後一個參數;
Esc, .
Alt+.
命令補全,路徑補全
命令補全:搜尋PATH環境變數所指定的每個路徑下以我們給出的字串開頭的可執行檔,如果多於一個,兩次tab,可以給出列表;否則將直接補全;
路徑補全:搜尋我們給出的起始路徑下的每個檔案名稱,並試圖補全;
2、管道、重新導向
管道------前一個命令的輸出,作為後一個命令的輸入
命令1 | 命令2 | 命令3 | ...
如:cat /var/log/message |less
find ./ -name ex* | xargs mv /backup
> 覆蓋輸出
>> 追加輸出
2> 重新導向錯誤輸出
2>> 追加方式
&> 重新導向標準輸出或錯誤輸出至同一個檔案
< 輸入重新導向
<< Here Document
:> file 清空一個檔案
對於Here Document舉個執行個體:
cat >> /etc/hosts << EOF
172.28.9.45www01.opsmysql.com
172.28.9.46www02.opsmysql.com
172.28.9.47www03.opsmysql.com
172.28.9.48www04.opsmysql.com
EOF
"*/5 * * * * /usr/sbin/ntpdate ntp.api.bz > /dev/null 2>&1
/dev/null 2>&1 : 意思是將標準輸出和錯誤輸出全部重新導向到/dev/null中
3、命令別名和命令替換
命令別名
alias CMDALIAS='COMMAND [options] [arguments]'
在shell中定義的別名僅在當前shell生命週期中有效;別名的有效範圍僅為當前shell進程;
ualias CMDALIAS
對於我們設定別名的命令,如果要使用沒有設定別名時的命令格式,即預設格式可以在命令前面加上: \
\CMD
對於別名我們還可以寫在設定檔中:
全域設定檔:/etc/bashrc
使用者設定檔:~/.bashrc
命令替換: $(COMMAND), 反引號:`COMMAND`
把命令中某個子命令替換為其執行結果的過程
如:
echo "The date time is : `date`"
echo "The date time is : $(date +%F)"
bash支援的引號:
``: 命令替換
"": 弱引用,可以實現變數替換
'': 強引用,不完成變數替換
4、命令列編輯
游標跳轉:
Ctrl+a:跳到命令列首
Ctrl+e:跳到命令列尾
Ctrl+u: 刪除游標至命令列首的內容
Ctrl+k: 刪除游標至命令列尾的內容
Ctrl+l: 清屏
5、檔案名稱通配:globbing
*: 任意長度的任一字元
?:任意單個字元
[]:匹配指定範圍內的任意單個字元
[abc], [a-m], [a-z], [A-Z], [0-9], [a-zA-Z], [0-9a-zA-Z]
[:space:]:空白字元
[:punct:]:標點符號
[:lower:]:小寫字母
[:upper:]: 大寫字母
[:alpha:]: 大小寫字母
[:digit:]: 數字
[:alnum:]: 數字和大小寫字母
# man 7 glob
[^]: 匹配指定範圍之外的任意單個字元
[[:alpha:]]*[[:space:]]*[^[:alpha:]]
6、Bash相關設定檔及變數
bash的設定檔:
全域配置
/etc/profile, /etc/profile.d/*.sh, /etc/bashrc
個人配置
~/.bash_profile, ~/.bashrc
profile類的檔案:
設定環境變數
運行命令或指令碼
bashrc類的檔案:
設定本地變數
定義命令別名
登入式shell如何讀取設定檔?
/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非登入式shell如何設定檔?
~/.bashrc --> /etc/basrc --> /etc/profile.d/*.sh
關於環境變數命令介紹:
1.echo 顯示某個環境變數值 echo $PATH
2.export 設定一個新的環境變數 export HELLO="hello" (可以無引號)
3.env 顯示所有環境變數
4.set 顯示本地定義的shell變數
5.unset 清除環境變數 unset HELLO
6.readonly 設定唯讀環境變數 readonly HELLO
常見的環境變數
PATH:決定了shell將到哪些目錄中尋找命令或程式
HOME:目前使用者主目錄
MAIL:是指目前使用者的郵件存放目錄
SHELL:是指目前使用者用的是哪種Shell
HISTSIZE:是指儲存曆史命令記錄的條數
LOGNAME:是指目前使用者的登入名稱
HOSTNAME:是指主機的名稱,許多應用程式如果要用到主機名稱的話,通常是從這個環境變數中來取得的
LANG/LANGUGE:是和語言相關的環境變數,使用多種語言的使用者可以修改此環境變數
PS1:是基本提示符,對於root使用者是#,對於普通使用者是$
PS2:是附屬提示符,預設是“>”。可以通過修改此環境變數來修改當前的命令符
位置變數:
$1, $2, ...$n
特殊變數:
$?:上一個命令的執行狀態傳回值,echo $0結果如果為0表示成功,非0表示失敗.
$0:擷取當前執行的shell指令碼的檔案名稱,通常結合basename使用
$*:擷取當前shell的所有參數,$1 $2 $3 ,注意與$#的區別
$#:擷取當前shell命令列中參數的總個數
$$:擷取當前shell的進程號(PID)
$!:執行上一個指令的PID
$@:這個程式的所有參數 "$1" "$2" "$3" "…"
注意:有時候變數名很容易與其他文字混淆,比如我們在某個變數的值後面追加內容:
num=2
echo "this is the $numnd"
這並不會列印出"this is the 2nd",而僅僅列印"this is the ",因為shell會去搜尋變數numnd的值,但是這個變數時沒有值的。可以使用花括弧來告訴shell我們要列印的是num變數:
num=2
echo "this is the ${num}nd"
這將列印: this is the 2nd
變數名不能以數字開頭!!!!!!!!!!!!!!!!
+++++++++++++++++++++++++++++++++++++++++++++++++++++
shell中如何進行算術運算:
A=3
B=6
1).let 算術運算運算式
let C=$A+$B
2).$[算術運算運算式]
C=$[$A+$B]
3).$((算術運算運算式))
C=$(($A+$B))
4).expr 算術運算運算式,運算式中各運算元及運算子之間要有空格,而且要使用命令引用
C=`expr $A + $B`
這些計算方法都是shell編程的基礎!!!
shell中關於字串的簡單操作:
取字串長度
A="admin"
echo ${$A} 或 expr length $A
字串的替換與刪除操作:
${變數#關鍵字}--------->若變數內容從頭開始的資料符合‘關鍵字’,則將符合的最短資料刪除
如:echo
${變數##關鍵字}--------->若變數內容從頭開始的資料符合‘關鍵字’,則將符合的最長資料刪除
${變數%關鍵字}--------->若變數內容從尾向前的資料符合‘關鍵字’,則將符合的最短資料刪
${變數%%關鍵字}--------->若變數內容從尾向前的資料符合‘關鍵字’,則將符合的最長資料刪除
${變數/舊字串/新字串}--------->若變數內容符合‘舊字串’則‘第一箇舊字串會被新字串取代
${變數//舊字串/新字串}--------->若變數內容符合‘舊字串’則‘全部的舊字串會被新字串取代
7、編程(條件判斷、迴圈控制)
下面總結下條件測試類型
整數測試
字元測試
檔案測試
條件測試的運算式:
[ expression ]
[[ expression ]] -----在Bash高版本中基本上只能用這個進階的了...上面那個會報錯!
test expression
整數比較:
-eq: 測試兩個整數是否相等;比如 $A -eq $B
-ne: 測試兩個整數是否不等;不等,為真;相等,為假;
-gt: 測試一個數是否大於另一個數;大於,為真;否則,為假;
-lt: 測試一個數是否小於另一個數;小於,為真;否則,為假;
-ge: 大於或等於
-le:小於或等於
間邏輯關係:
邏輯與: &&
第一個條件為假時,第二條件不用再判斷,最終結果已經有;
第一個條件為真時,第二條件必須得判斷;
邏輯或: ||
注意:[ 條件1 -a 條件2 ] 等價於 [ 條件1 ] && [ 條件2 ]
還有一點要注意:
可以
[[ 條件1 && 條件2 ]]這樣使用
不可以
[ 條件1 && 條件2 ]這樣使用
字元測試:
==:測試是否相等,相等為真,不等為假
!=: 測試是否不等,不等為真,等為假
\>
\<
-n string: 測試指定字串是否為空白,空則真,不空則假
-z string: 測試指定字串是否不空,不空為真,空則為假
string ="" 字串為空白
string !="" 字串不為空白
檔案測試:
-e FILE:測試檔案是否存在
-f FILE: 測試檔案是否為普通檔案
-d FILE: 測試指定路徑是否為目錄
-s FILE: 判斷檔案是否存在且大小大於0
-r FILE: 測試目前使用者對指定檔案是否有讀取許可權
-w FILE: 檔案是否可寫
-x FILE: 檔案是否可執行
再簡單說下指令碼退出狀態代碼
exit: 退出指令碼
exit #
如果指令碼沒有明確定義退出狀態代碼,那麼,最後執行的一條命令的退出碼即為指令碼的退出狀態代碼;
通常:
# 是 0 表示正常退出
# 非 0 表示錯誤退出
+++++++++++++++++++++++++++++++++++++++++++++++++
條件判斷--if
單分支if語句
if 判斷條件; then
statement1
statement2
...
fi
雙分支的if語句:
if 判斷條件; then
statement1
statement2
...
else
statement3
statement4
...
fi
多分支的if語句:
if 判斷條件1; then
statement1
...
elif 判斷條件2; then
statement2
...
elif 判斷條件3; then
statement3
...
else
statement4
...
fi
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
選擇結構--case
case SWITCH in
value1)
statement
...
;;
value2)
statement
...
;;
*)
statement
...
;;
esac
說明:value1) 是Regex樣式,可以用下面字元:
* 任意長度的字串
C* 表示以C字元開頭的字串
? 任意單個字元,???? 表示4個字元的字串
[abc] a, b, 或c三字元其中之一,如:[abc]123,匹配a123或b123或c123。
[a-n] 從a到n的任一字元
| 多重選取,分隔字元
+++++++++++++++++++++++++++++++++++++++++++++
迴圈控制---for
兩種用法:
for 變數 in 列表; do
迴圈體
done
for (( expr1 ; expr2 ; expr3 )); do
迴圈體
done
迴圈控制---while
while CONDITION; do
statment
done
進入迴圈:條件滿足
退出迴圈:條件不滿足
while的特殊用法一(死迴圈):
while :; do
statment
done
while的特殊用法二(從某個檔案中讀取行):
while read LINE; do
statment
done < /PATH/TO/SOMEFILE
方法二另外一種寫法:
cat ip.txt | while read line
do
echo $line
done
迴圈控制---until
until跟while相反,可參照while
until CONDITION; do
statement
...
done
判斷條件是否成立,不成立就執行迴圈體,成立就退出!
迴圈控制語句
break
中斷迴圈,而後執行迴圈後面的語句;預設是跳出一層迴圈,如果要跳出多層迴圈,可以用 break n(n是大於1的數字,也就次數)。
continue
中斷當前這一次迴圈,提前進入下一次迴圈,預設跳過一層迴圈,如果要跳過多層迴圈,可以用 continue n(n是大於1的數字,也就次數)。
++++++++++++++++++++++++++++++++++++++++++++++++++++++
select (產生菜單選擇)
select 運算式是一種bash的擴充應用,尤其擅長於互動式使用,使用者可以從一組不同的值中進行選擇.
select 命令可以建立簡單的列表,結構類似for迴圈,一般與case語句結合使用。
下面寫一個執行個體:
#!/bin/bash
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do
break
done
echo "You have selected $var"
8、bash中的數組使用
數組賦值方式:
(1) array=(var1 var2 var3 ... varN)
(2) array=([0]=var1 [1]=var2 [2]=var3 ... [n]=varN)
(3) array[0]=var1
arrya[1]=var2
...
array[n]=varN
注意:shell中數組的下標預設是從0開始的!
擷取數組元素個數或者長度:
(1) ${#array[@]}
(2) ${#array[*]}
顯示數組元素:
echo ${array[*]} #顯示所有元素
echo ${array[@]}
echo ${array[@]:0}
echo ${array[0]} #顯示第一個元素
echo ${array[@]:2} #不顯示數組中前兩個元素
echo ${array[@]:0:2} #從第一個元素開始顯示兩個元素
刪除數組中的元素:
unset array[2] #刪除第三個元素
unset array #刪除整個數組
子串刪除:
echo ${array[@]#t*e} # 左邊開始最短的匹配:"t*e",這將匹配到"thre"
echo ${array[@]##t*e} # 左邊開始最長的匹配,這將匹配到"three"
echo ${array[@] %o} # 從字串的結尾開始最短的匹配
echo ${array[@] %%o} # 從字串的結尾開始最長的匹配
子串替換:
echo ${array[@] /o/m} #第一個匹配到的,會被刪除
echo ${array[@] //o/m} #所有匹配到的,都會被刪除
echo ${array[@] //o/} #沒有指定替換子串,則刪除匹配到的子符
echo ${array[@] /#o/k} #替換字串前端子串
echo ${array[@] /%o/k} #替換字串後端子串
迴圈列出數組元素:
#!/bin/bash
arr=(ab bc cd)
lenarr=${#arr[@]}
for (( i=0; i<$lenarr}; i++ )); do
echo ${arr[$i]}
done
#!/bin/bash
arr=(ab bc cd)
lenarr=${#arr[@]}
i=0
while [[ $i -lt $lenarr ]]
do
echo ${arr[$i]}
let i++
done
一個執行個體:
#!/bin/bash
# 設定IFS將分割符 設定為 分行符號(\n)
OLDIFS=$IFS
IFS=$'\n'
# 讀取檔案內容到數組
fileArray=($(cat file.txt))
# restore it
IFS=$OLDIFS
tLen=${#fileArray[@]}
# 迴圈顯示檔案內容
for (( i=0; i<${tLen}; i++ )); do
echo "${fileArray[$i]}"
done
9、shell編程技巧和編程規範
檢測文法相關:bash -n 指令碼名
命令追蹤:bash -x 指令碼名
shell輸入和輸出中:
read 用法
cat 特殊用法
echo 特殊用法
後台執行命令:& nohup
如果正在運行一個進程,而且覺得在退出帳戶時該進程還不會結束,那麼可以使用nohup命令。該命令可以在你退出帳戶之後繼續運行相應的進程。Nohup就是不掛起的意思( no hang up)。
nohup命令的一般形式為nohup command &
shift 用法
.......
.........
..........
後面略!
簡單說下編程規範:
1.檔案注釋說明
在編寫的每個指令檔中,應當包含檔案注釋、指令碼用途簡單描述、版本、作者等...如:
#!/bin/bash
#Description: .......
#Date: xxxx-xx-xx
#Version: ....
#Author: Andy
2.代碼注釋
3.函數注釋--說明該函數的功能
4.變數命名正常化
取名要說明這個變數代表的含義
變數名或函數名不要太長
名稱盡量使用大寫或大寫開頭
如:
Passwd
Num_Count
5.代碼注意縮排
原創作品,允許轉載,轉載時請務必以超連結形式標明文章 原始出處 、作者資訊和本聲明。否則將追究法律責任。