BASH使用基礎
關於命令及命令類型
對於使用的命令BASH使用hash表,以加速下次的尋找,為添加一個經常使用的命令,可以使用hash cmd
BASH在執行命令時對路徑中找到的同名命令按以下的類型順序執行:別名 keywords 函數 內建命令 可執行檔或指令碼
BASH在執行使用者輸入的一條指令時,首先要判斷命令的類型,可以使用type cmd來查看cmd是類型。
enable命令用來決定是否開啟某個內建的命令,可以用enable -n cmd來禁用某個內建命令。
command命令用來消除別名和函數的尋找。
builtin命令將只尋找內建命令,而忽略函數和可執行檔。
作業控制:jobs %1 fg bg kill stop等
別名:alias dir='dir -l' unalisa dir
操作目錄棧:dirs pushd popd
檔案名稱替換:dir d[1-3] ls .bash{rc,profile} 支援[]對數字及{}對字串的集合
變數
變數聲明:declare -a 數組 -f 函數 -i 整數 -r 唯讀 -x 匯出變數
本地變數只在其所聲明的shell中有效,唯讀變數不能被修改,除非重新聲明其屬性
常見的環境變數:
BASH_VERSION DIRSTACK EUID EDITOR GROUPS HISTFILE HISTSIZE HOME LANG PWD OLDPWD PATH
PPID PS1-4 RANDOM SHELL UID
export var = value -f 匯出的變數為函數 -n 將全域轉為局部變數 -p只列印匯出的變數
非唯讀變數可以通過unset清除、
變數替換
${var:-word} 如果變數var已經設定且非空,結果為var的值,否則結果為word
${var:=word} 如果變數var已經設定且非空,結果為var的值,否則設定var為word
${var:+word} 如果變數var已經設定且非空,則設定var的值為word;否則不替換
${var:?word} 如果變數var已經設定且非空,則替換為word,否則退出shell。
${var:n} 替換為從n開始的子串
${var:n:len} 替換為從n開始長len的子串
變數擴充
${var%pattern} 去掉最小匹配的尾碼 echo ${PWD%/*} 顯示當前的父目錄路徑
${var%%pattern} 去掉最大匹配的尾碼
${var#pattern} 去掉最小匹配的首碼
${var##pattern} 去掉最大匹配的首碼 echo ${PWD##*/} 顯示目前的目錄名稱
${#var} 替換為變數字元個數
特殊變數
$ 當前SHELL的PID
? 前一個命令的退出狀態
! 後台執行的上一個工作的PID
讀取使用者輸入
read 從終端讀取輸入存入內建變數REPLY
read var 從終端讀取輸入存入變數var
read first .. last 從終端讀取多個變數依次存入,若輸入較多,則最後一個變數成為包含多個值的字串
read -a array 從終端讀取多個值存入數組中
read -p pmtstring var 向終端輸出提示串,然後讀入輸入到var中
read -r line 讀取一行,並允許/
變數類型轉換
如果變數在聲明時沒確定類型,則變數根據賦值情況可以動態轉換類型,但如果聲明時變數類型已經確定,若賦值為其他類型,將導致原有資料丟失或出錯。除非重新宣告類型。
對於整數類型的變數,則在命令列支援演算法擴充,如num=3*4,支援"",不支援空格。
進位
var=16#abc var為16進位數abc
輸出
printf "The number is %.2f/n" 100
echo -ne "hello/nworld/n" -e 表示需要解析逸出字元,-n 表示不自動添加分行符號
位置參數
$0 1-0 ${10}
$# 求值位置參數個數
$* 求值所有位置參數
"$*"
$@
"$@"
引用
() 命令組,建立子SHELL執行
{} 命令組,不建立子SHELL
' ' 保護所有的元字元不被解析,想列印',必須放在雙引號內,或者使用/轉義
" " 只允許變數和命令替換,保護其餘的元字元不被解析
命令替換
`cmd`
$(cmd)
二者結果都是一個字串,在使用結果時,如果加"",則保留換行,否則丟失換行。
數學運算式擴充
$[ exp ]
$(( exp ))
f
數組
declare -a array=(item1 item2 ...)
數組元素的引用 ${array[i]}
引用整個數組 ${array[*]}
unset array
函數定義
function f()
{
cmd;cmd;
}
I/O重新導向
find . name /*.c print > foundit 2>&1
命令列參數
set可用來設定位置參數,使用set --將清除所有位置參數
$*與$@的區別只在於" "時,當$*放在""內時,參數表成為單個字串,而$@放在""內時,每個參數都被引號括住。
運算式
評估運算式
expr $[3+4] $[ 3+4 ] $(( 3+4 ))
let算術擴充
let i=i+1 支援任何C類型的運算子,但只支援整形數運算
bash不支援小數運行,因此需要在bc或者awk中進行相應的運行,再把結果回。由於bash沒有浮點型,所以小數是以字串表示。
測試運算式
測試可以使用test或者單純的[ expr1 cmp expr2],結果儲存於?變數中,即test與[]等價
字串測試
[ str1 = str2 ] str1與str2相同或==
[ str1 != str2 ] st1與str2不相同
[ str ] str非空
[ -z str ] str的長度為0
[ -n str ] str的長度非0
[ -l str ] str的長度
[ str1 -a str2 ] and
-o or
! not
複合條件測試
[[ p1 && p2 ]] p1與p2均為真
[[ p1 || p2 ]]
[[ !p2 ]]
整數測試
[ num1 -eq num2 ]
[ numb1 -ne num2 ]
gt ge lt le
檔案屬性測試
[ file1 nt file2 ] 檔案1比檔案2新
[ file1 ot file2 ]
[ file1 ef file2 ]
[-d file] file為目錄
-b -c -p -L -S 塊檔案,字元檔案,管道,連結,socket
-e -f 檔案存在,常規檔案
-G 檔案存在且擁有有效GID
-O 檔案存在且擁有有效UID
-g 設定GID
-k 設定stick位
-r -w -x 檔案可讀,可寫,可執行檔
-s 檔案大小非0
-t 檔案fd在終端開啟
-u setUID位設定
測試表達可以與let的運算擴充及(( ))中的C型運算擴充是等價的,後者也許更容易理解,C-like。
條件控制
if command
then
command
command
fi
if test expression
then
command
fi
if [ string/numeric expression ] then
command
fi
if [[ string expression ]] then
command
fi
if (( numeric expression ))
if command
then
command(s)
else
command(s)
fi
if command
then
command(s)
elif command
then
commands(s)
elif command
then
command(s)
else
command(s)
fi
空命令 :
分支跳轉
case variable in
value1)
command(s)
;;
value2)
command(s)
;;
*)
command(s)
;;
esac
迴圈
for variable in word_list
do
command(s)
done
while condition
do
command(s)
done
until command
do
command(s)
done
構建菜單的select
select program in 'ls -F' pwd date
do
$program
done
中斷迴圈
break [n] 從第n層迴圈中跳出
continue [n] 繼續第n層迴圈
捕獲訊號
訊號列表
1) SIGHUP 9) SIGKILL 17) SIGCHLD 25) SIGXFSZ
2) SIGINT 10) SIGUSR1 18) SIGCONT 26) SIGVTALRM
3) SIGQUIT 11) SIGSEGV 19) SIGSTOP 27) SIGPROF
4) SIGILL 12) SIGUSR2 20) SIGTSTP 28) SIGWINCH
5) SIGTRAP 13) SIGPIPE 21) SIGTTIN 29) SIGIO
6) SIGABRT 14) SIGALRM 22) SIGTTOU 30) SIGPWR
7) SIGBUS 15) SIGTERM 23) SIGURG
8) SIGFPE 16) SIGSTKFLT 24) SIGXCPU
trap 'command; command' signal-number-list
trap 'command; command' signal-name-list 處理訊號,當收到singal-list中的訊號後,執行 ''中的命令
trap singal 重設訊號處理函數
trap 列出已經設定訊號處理
調試指令碼
bash -x script 顯示命令執行過程,及結果
bash -v script 顯示指令碼中的各行
bash -n script 解釋但不執行
附錄:
常用命令
script myfile 將終端互動資訊儲存在myfile中,使用control+d退出
fuser -n tcp 22 獲得開啟tcp 22的進程
lsof 獲得進程開啟的檔案
快速鍵
ctrl +a 到命令列首
ctrl + c 中斷命令執行
ctrl + d 關閉中斷
ctrl + e 到命令列尾
ctrl + u 剪下游標到行首
ctrl + k 剪下游標到行尾
ctrl + y 粘貼剛刪除字元
ctrl + r 在曆史命令中搜尋
!! 重複執行最後一次命令
!$ 上次命令執行的參數