shell指令碼學習筆記 (一)
一、位於第一行的#!
當一個檔案中開頭是#!時,核心會掃描改行的剩餘部分,看是否存在可用來執行程式的直譯器的完整路徑,此外核心還會掃描是否有一個選項要傳給直譯器,核心會以指定的選項來引用直譯器,在搭配命令列的其他部分。
例如:
有一個csh指令碼,名為/usr/ucb/whizprog
它的第一行為#!/bin/csh -f,且/usr/ucb位於PATH中,
於是當用戶輸入whizprog -q /dev/tty01時,核心解釋#!命令列後就會以如下方式引用csh:
/bin/csh -f /usr/ucb/whizprog -q /dev/tty01
在實際編寫指令碼時,指令碼是否具有可移植性取決於是否有完整的路徑名稱。
在書寫指令碼時不使用任何選項,也可以在指令碼後面新增" -" ,基於安全性的考慮,這可以避免某種程度上得欺騙是攻擊。
例:
#! /bin/sh -
二、shell的基本元素
'-' 以及'--'表示選項
“;”用來分隔同一行裡的多條命令
“&”使shell在後臺執行其前面的命令。
shell識別的三種基本命令:內建命令、shell函式、外部命令。在這裡重點描述一下shell的外部命令:
shell的外部命令就是指shell的副本所執行的命令,其基本過程如下:
a)建立一個新的程序,此程序為shell的一個副本;
b)在新程序中,在PATH指定的目錄中,查詢指定的命令。(如果命令名稱裡有"/"則忽略路徑查詢的步驟)
c)在新程式中,用查詢到的命令替換原有的shell程式並執行
d)程式執行完以後,原有的shell繼續執行讀取下一行命令,執行上訴步驟。
變數:shell中變數的賦值方式為 變數名緊跟著“=”,然後是值,其中不能出現任何空格。當在shell想取變數值時,需要在前面加上$符號。
當需要將多個變數連線在一起的時候需要使用引號: fullname="$first $second $third"
echo和printf都可用於輸出,printf的用法大體與C語言中類似除了一點:如果shell中呼叫printf時,引數比格式化宣告多,則多出來的引數會迴圈依次的與格式化宣告匹配,直到處理完所有的引數。
三、重定向和管道
< 輸入重定向
> 輸出重定向
>>附加到檔案
| 管道
四、 tr命令
tr [option] source replac 將標準輸入輸出中德source字元 替換成replac ,其中source 和replac中的字元是逐個對應的,多出的字元不進行替換。
option:
-c, -C 替換的內容為不在source內的字元
-d 刪除 source中字元
-s 若標準輸入中 重複出現source中的某個字元,則將重複出現的字元替換為一個
五、特殊檔案
/dev/null:位桶,所有寫入的內容都會被丟棄,而讀取它則會立刻返回檔案結束描述符EOF
/dev/tty:程式會自動將它定位到一個終端,然後在與程式結合
stty 命令用於控制終端的各種設定
-echo 關閉自動列印輸入字元的回顯功能
+echo 開啟自動列印輸入字元的回顯功能
六、位置引數
所謂位置引數即是指shell指令碼的命令列引數。從1開始,當它超過9時應該用大括號把數字括起來。
例: $1 ${10}
七、簡單的執行跟蹤
將執行跟蹤功能開啟後,shell會顯示每個執行的命令,並在前面加上“+”。
可以通過給PS4變數賦值改變shell的列印方式
執行時可以用:“sh -x shell指令碼名稱”的方式開啟執行跟蹤功能
也可以在shell指令碼中 用“set -x” 開啟執行跟蹤功能 然後再用"set +x"關閉執行跟蹤功能
八、LANG, LC_ALL
LANG變數用來設定locale的預設值
LC_ALL用來覆蓋掉所有其他的LC_xxx變數
可以通過 locale -a 檢視當前系統支援的所有locale