1. 程式人生 > >shell指令碼學習筆記 (一)

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