Linux shell的一些特性

    1.變量替換及應用


${var:-word}              如果var存在且非空,則返回var,否則返回word但是不替換var
${var:+word}             如果var存在且非空,則返回word(不替換var),否則返回var
${var:=word}             如果var存在或爲空,則返回var,否則返回word且替換var
${var:?message}       如果var存在且非空,返回var,否則返回"var:message"這個字符串
${var:offset}               在var中提從offset到其末尾的子字符串
${var:offset:length}    在var中從offset開始提取length長的子字符串
${var#pattern}           返回刪除掉var中開頭pattern最短匹配後剩餘的字符串
${var##pattern}         返回刪除掉var中開頭pattern最長匹配後剩餘的字符串
${var%pattern}          返回刪除掉var中結尾pattern最短匹配後剩餘的字符串
${var%%pattern}       返回刪除掉var中結尾pattern最長匹配後剩餘的字符串
${var/pattern/string} 用string替換var中開頭pattern的最短匹配
${var//pattern/string} 用string替換var中開頭pattern的最長匹配


例子:
${*:-.}                如果沒有提供位置參數則使用當前目錄
${path##*/}       從全路徑中獲取基本文件名,等價於basename(外部程序沒shell內置機制效率高)
${path%/*}        獲取目錄名,等價於dirname(外部程序沒shell內置機制效率高)


    2.命令替換及應用


$(command)
`command`


ROOT=`pwd` <=> ROOT=$(pwd)


    3.數學運算


let i=i+1 bash             內置變量(不能加空格)
((i += 2))                     運算符可用空格隔開
i=`expr 3 \* 5`              注意需要轉義符
i=$(expr 3 \* 5)
i=`echo "scale=2; $TSIZE/$SSIZE*100" | bc -l`       bc命令不一定每個linux用戶都安裝了
declare -i a=1 b=2;declare c=a+b           聲明稱整數來計算


    4.數組及應用


數組初始化:
var[index]=value           整數做下標
var[string]=value            字符串做下標
var=(value1 value2 ...)   空格隔開


清空數組:
var=
unset var
unset var[value]


引用數組數據:
${var}                     引用不帶下標的數組,得到數組第一個元素
${var[variable]}      下標使用變量時不需要美元符號引用
${var[@]}                得到數組所有元素
${var[*]}                 得到數組所有元素
${#var[@]}             得到數組元素個數
${#var[*]}               得到數組元素個數


    5.特殊變量


$$ 當前shell的PID
$! 在後臺運行的最後一個作業的PID
$? 關於上個執行指令的回傳碼
$0 當前shell的名字
$n (n:1-) 位置參數
$# 參數個數
$* 所有位置參數組成的單一字符串
$@ 每個位置參數的字符串組合成的


$*和$@的區別
$*將所有位置參數作爲單一字符串
$@是所有位置參數的字符串組合


function "$*"           函數參數只有一個
function "$@"        函數參數有多個


    6.命令行選項


通常使用getopts,第一個冒號表示用戶鍵入錯誤選項時不提示
$OPTARG表示選項對應的參數值,$OPTIND表示命令行選項的索引


模板:
while getopts ":X1:X2:..." opt;do
case $opt in
   x1) value_x1=$OPTARG;;
   X2) ..;;
esac
done
shift $(($OPTIND-1))


    7.命令行解析


一個shell命令行的完整處理過程:


1).將輸入分隔成記號(記號包括單詞,關鍵字,I/O定向符,分號等)
2).檢測每個命令的第一個記號,若爲開發關鍵字(像if等)則繼續匹配一個完整的符合命令,重複處理完成,返回步驟1。
3).別名檢測(檢測第一個記號是別名就進行替換,返回步驟1)
4).大括號擴展(a{b,c}擴展爲ab ac)
5).~符號擴展(如果存在替換爲$HOME)
6).變量(參數)替換(以$開頭的表達式)
7).命令替換(對$(string)形式進行)
8).算術替換(對$((string))進行計算)
9).單詞分隔(使用$IFS中的字符分隔參數,命令,算術替換中的部分成單詞)
10).路徑名擴展(通配符擴展,例如*,/等)
11).命令查詢(函數>內置命令>腳本和可執行程序)
12).運行命令(設置完I/O重定向後執行命令)


單引號‘’(繞過前10個步驟)
單引號中的命令只能執行路徑擴展,命令查找


雙引號""(繞過步驟1~5,9,10)
雙引號中可以使用參數替換,命令替換,算術替換


命令查找順序可以用command,builtin,enable來修改
command刪除別名和函數查找
builtin只查找內置命令
enable -a顯示所有命令及其是否可用


eval通知shell接受eval參數,並再次通過命令行處理的所有步驟來運行
所以被繞過的步驟可以重新解析


shell解析命令順序
別名>關鍵字>函數>內置命令>腳本和可執行程序


    8.進程控制


作業編號指當前運行在用戶shell下的後臺進程(不同shell窗口下的作業毫無關係)
進程ID指當前運行在整個系統上的所有用戶的進程


作業控制:


jobs -l列出作業的完整信息


引用後臺作業的方式:
fg %N            作業編號N
fg %string     作業命令名以string開始的作業
fg %?string   作業命令包含的string的作業
fg %+           最近被調用的後臺作業(引用被放到後臺的最新作業)
fg %%          同上
fg %-            第二個最近被調用的後臺作業
fg (不帶%)    作業進程ID


使用的作業控制的好處:
有可能前臺的作業運行時間很長,而你還想用控制終端做其他操作,這是就可以將其放到後臺
CTRL-Z即將當前作業放到後臺


kill用法:
kill參數可以使進程ID,作業編號,進程命令名
kill默認發送TERM信號到目標,但可以改變所發信號類型
kill -l 列出支持的所有信號名稱和編號列表
CTRL-C   INIT
CTRL-\     QUIT
CTRL-Z   TSTP
kill   TERM


stty signame char可以綁定信號到什麼控制鍵上 例如:stty intr ^X


kill         %作業編號
kill           進程ID
kill          進程名
kill          信號類型 參數


協同程序:
shell命令行下協同,執行命令之間使用&即可
腳本里面,最後必須加上wait命令保證所有後臺作業都完成


模式:
命令1 &
...
命令2
wait


進程使用系統資源的特性:CPU密集型,I/O密集型,交互式


對於I/O密集型使用一個大型計算的作用會較好
對於CPU密集型,多通過shell併發執行回提高效率


當在一個多CPU計算機上啓動一個後臺作業時,計算機會將其賦予到下一個可用處理器
這意味着兩個作業時間上運行在同一時刻,所有能提升效率


子shell:
子shell繼承的東西:
1)當前目錄
2)環境變量
3)標準輸入,標準輸出,標準錯誤,以及其他任何打開的文件描述符
4)被忽略的信號(trap)
未繼承的東東:
1)shell變量(除了環境變量和定義在環境文件中.bashrc的變量)
2)沒被忽略的信號處理


exec精髓,替換本shell來執行exec參數中的命令對本shell一直髮生影響
exec 2>errlog 把腳本中所有錯誤寫到errlog文件中(放在腳本開頭)
exec switch_root /newroot "/sbin/init" 啓動腳本中常常見到

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章