最近在linux下面編寫shell指令碼,差不多是邊學邊寫。在此記錄一些學習心得。
一)shell的引號。
shell的引號有單引號',雙引號",反引號`。
由單引號括起來的字元都作為一般字元出現。特殊字元用單引號括起來以後,也會失去原有意義,而只作為一般字元解釋。
由雙引號括起來的字元,除$、倒引號(`)和反斜線(\)仍保留其特殊功能外,其餘字元均作為一般字元對待。“$”表示變數替換,即用其後指定的變數的值來代替$和變數;倒引號表示命令替換;僅當“\”後面的字元是下述字元之一時,“\”才是逸出字元,這些字元是:“$”、“`”、“"”、“\”或分行符號。逸出字元告訴Shell不要對其後面的那個字元進行特殊處理,只是當作一般字元。
倒引號括起來的字串被shell解釋為命令列,在執行時,Shell會先執行該命令列,並以它的標準輸出結果取代整個倒引號部分。
二)目錄許可權。
檔案或目錄的存取權限分為唯讀(r),唯寫(w)和可執行(x)三種。
當我們用ls -l命令的時候,會看到如下內容
其中第一列我們看到了-rw-r--r--的字元,這個就表示當前的檔案的許可權。
橫線代表空許可。注意這裡共有10個位置。第一個字元指定了檔案類型。在通常意義上,一個目錄也是個檔案。如果第一個字元是橫線,表示是個非目錄的檔案。如果是d,表示是個目錄。除第一個位置外,剩下的每連續三個表示一個許可權,第一個連續三字元表示檔案擁有者的許可權,比如這裡的”rw-“表示檔案擁有著具有可讀可寫的許可權。第二個連續三字元”r--“表示檔案擁有著所在組具有的許可權,這裡的”r--“表示唯讀。後面連續三字元表示所有使用者的許可權,也是唯讀。
在使用權限設定中,我們為了簡化這種使用權限設定,通常把r、w、x分別用4、2、1表示,然後把它們相加表示檔案的許可權。比如上面的兩個檔案的許可權就是644。又比如一個檔案的許可權是754,那就表示檔案的擁有者具有可讀可寫可執行檔許可權,所在組具有讀和執行的許可權,其他使用者具有讀的許可權。
我們可以通過chmod來修改一個檔案的許可權。這裡有兩種方式,首先是數字設定法,我們只需要運行下面的命令
或者使用文字設定法,如下
文字設定法中的u+x,g-w-r,o-x-r就表示設定許可權,其中u,g,o分別表示檔案擁有者,所在組使用者,其他使用者,而+,-對應增加與刪除許可權。
當然使用chmod修改檔案許可權只能是超級使用者和檔案的擁有者。
除此之外,我們還能使用者chgrp修改檔案所屬組,chown修改檔案所屬使用者或組。
文法:chgrp [選項] 使用者組 檔案
文法:chown [選項] 使用者或組 檔案
三)變數。
shell中的變數不需要聲明,賦值的話直接[變數名=值]就可以了。比如
num=1me=fly
在shell中變數引用有幾個需要注意的地方,比如你在指令碼中使用下面的語句時
echo "I'm ${me}Baby"
這時候就不能直接使用$meBaby,因為shell解釋的時候就會去找meBaby這個變數。而你只有me這個變數。
在shell中實現變數的運算時,需要注意幾個地方,看下圖的執行結果
從上面的執行結果我們可以看出,使用shell變數就行運算的時候,可以使用中括弧,雙小括弧,以及expr運算關鍵字。
除了以上基本的變數外,shell裡面還有一些特殊的參數。如下面的參數:
$0 = shell名稱或shell指令碼名稱 $1 = 第一個shell參數 ... $9 = 第九個shell參數 $# = 位置參數的個數 "$*" = "$1 $2 $3 $4 .. $n",以一個單字串顯示所有向指令碼傳遞的參數。與位置變數不同,此選項參數可超過9個。 "$@" = "$1" "$2" "$3" "$4" .. "$n",與$#相同,但是使用時加引號,並在引號中返回每個參數。 $# 傳遞到指令碼的參數個數。 $- 顯示shell使用的當前選項,與set命令功能相同。 $? = 最近執行的命令的退出狀態,0表示沒有錯誤,其他任何值表明有錯誤。 $$ = 當前shell指令碼的PID。 $! = 最近啟動的後台作業的PID。 形式 如果設定了var 如果沒設定var ${var:-string} $var string ${var:+string} string null ${var:=string} $var string (並執行var = string) ${var:?string} $var 返回string然後退出 形式 結果 ${var%suffix} 刪除位元於var結尾的最小匹配模式 ${var%%suffix} 刪除位元於var結尾的最大匹配模式 ${var#suffix} 刪除位元於var開頭的最小匹配模式 ${var##suffix} 刪除位元於var開頭的最大匹配模式
四)條件與迴圈。
跟其他程式設計語言一樣,shell中包含if條件陳述式,while,for,until迴圈,以及case和select語句。首先介紹if條件陳述式
if語句結構[if/then/elif/else/fi],其中[ ]與變數之間有空格。
if [ $y -eq 1 ];theny=$(($y+1))elsey=1fi
shell命令,可以按照分號分割,也可以按照分行符號分割。如果想一行寫入多個命令,可以通過“';”分割。
num=3;if [ $num -eq 1 ] ;then echo 1; elif [ $num -eq 2 ] ;then echo 2;else echo 3;fi;
在if條件陳述式中,可以對數字字串進行大小,匹配比較,還可以對檔案夾、檔案的許可權、存在與否進行判斷。
五)函數。
六)時間。
七)grep,sed,awk,tr等工具的使用。
我們從例子入手,下面有一個檔案f中的網域名稱取出並排序,內容如下,
http://www.fly_sky520.org/index.htmlhttp://www.fly_sky520.org/1.htmlhttp://post.fly_sky520.org/index.htmlhttp://mp3.fly_sky520.org/index.htmlhttp://www.fly_sky520.org/3.htmlhttp://post.fly_sky520.org/2.html
*注意,各行之間有空行。下面看我的操作
1)首先利用grep與awk工具。
該方法先利用grep -v 取非空行資料,-v參數是反向檢索的意思。效果如下:
然後利用awk工具取以"/"分隔字元分割的第三個參數,也就是網域名稱了。
最後利用sort進行排序,用nuiq -c計數
所以第一個完整命令就是
cat f | grep -v '^$'|awk -F/ '{print $3}'|sort|uniq -c
2)利用tr與grep工具
首先利用tr工具的替換功能
再利用grep工具尋找包含網域名稱的項
最後排序計數
所以完整命令就是
cat f |tr "\/" "\n" | grep fly | sort | uniq -c
3)利用cut與tr工具
首先使用cut工具取出網域名稱
cut -d/ -f3的意思就是把檔案內容以“/”作為分隔字元,並去取出第三部分顯示。-d就是自訂分隔字元的意思,預設分隔符號為定位字元,-f就是顯示地區
然後,我們再利用tr工具去除空行
最後排序計數
所以最後的方法為
cut -d/ -f3 f|tr -s '\n'|sort | uniq -c
4)利用sed工具
首先利用sed工具去除空行
sed命令中d為刪除的意思。//之間為Regex^$表示空行。然後再利用sed的‘s///g’字元替換功能
最後還是排序計數
sed的編輯功能相當強大,比如我要修改設定檔f中【name = “Fly” 】的name為Sky。我只需要輸入以下命令
其中-i就是直接修改檔案內容的選項,這個命令的操作就是通過/name/先尋找出name行,然後修改對應的值。
下面是一些sed的例子
6. 執行個體 刪除:d命令 $ sed '2,$d' example-----刪除example檔案的第二行到末尾所有行。 $ sed '$d' example-----刪除example檔案的最後一行。 替換:s命令$ sed -n 's/^test/mytest/p' example-----(-n)選項和p標誌一起使用表示只列印那些發生替換的行。也就是說,如果某一行開頭的test被替換成mytest,就列印它。 $ sed 's/^192.168.0.1/&localhost/' example-----&符號表示替換換字串中被找到的部份。所有以192.168.0.1開頭的行都會被替換成它自已加 localhost,變成192.168.0.1localhost。$ sed -n 's/\(love\)able/\1rs/p' example-----love被標記為1,所有loveable會被替換成lovers,而且替換的行會被列印出來。 $ sed 's#10#100#g' example-----不論什麼字元,緊跟著s命令的都被認為是新的分隔字元,所以,“#”在這裡是分隔字元,代替了預設的“/”分隔字元。表示把所有10替換成100。 選定行的範圍:逗號$ sed -n '/test/,/check/p' example-----所有在模板test和check所確定的範圍內的行都被列印。 $ sed -n '5,/^test/p' example-----列印從第五行開始到第一個包含以test開始的行之間的所有行。$ sed '/test/,/check/s/$/sed test/' example-----對於模板test和west之間的行,每行的末尾用字串sed test替換。 多點編輯:e命令 $ sed -e '1,5d' -e 's/test/check/' example-----(-e)選項允許在同一行裡執行多條命令。如例子所示,第一條命令刪除1至5行,第二條命令用check替換test。命令的執 行順序對結果有影響。如果兩個命令都是替換命令,那麼第一個替換命令將影響第二個替換命令的結果。 $ sed --expression='s/test/check/' --expression='/love/d' example-----一個比-e更好的命令是--expression。它能給sed運算式賦值。 從檔案讀入:r命令 $ sed '/test/r file' example-----file裡的內容被讀進來,顯示在與test匹配的行後面,如果匹配多行,則file的內容將顯示在所有匹配行的下面。 寫入檔案:w命令 $ sed -n '/test/w file' example-----在example中所有包含test的行都被寫入file裡。 追加命令:a命令 $ sed '/^test/a\\--->this is a example' example<-----'this is a example'被追加到以test開頭的行後面,sed要求命令a後面有一個反斜線。 插入:i命令 $ sed '/test/i\\ new line -------------------------' example 如果test被匹配,則把反斜線後面的文本插入到匹配行的前面。 下一個:n命令 $ sed '/test/{ n; s/aa/bb/; }' example-----如果test被匹配,則移動到匹配行的下一行,替換這一行的aa,變為bb,並列印該行,然後繼續。 變形:y命令 $ sed '1,10y/abcde/ABCDE/' example-----把1--10行內所有abcde轉變為大寫,注意,Regex元字元不能使用這個命令。 退出:q命令 $ sed '10q' example-----列印完第10行後,退出sed。 保持和擷取:h命令和G命令$ sed -e '/test/h' -e '$G example-----在sed處理檔案的時候,每一行都被儲存在一個叫模式空間的臨時緩衝區中,除非行被刪除或者輸出被取消,否則所有被處理的行都將 列印在螢幕上。接著模式空間被清空,並存入新的一行等待處理。在這個例子裡,匹配test的行被找到後,將存入模式空間,h命令將其複製並存入一個稱為保 持緩衝區的特殊緩衝區內。第二條語句的意思是,當到達最後一行後,G命令取出保持緩衝區的行,然後把它放回模式空間中,且追加到現在已經存在於模式空間中 的行的末尾。在這個例子中就是追加到最後一行。簡單來說,任何包含test的行都被複製並追加到該檔案的末尾。 保持和互換:h命令和x命令 $ sed -e '/test/h' -e '/check/x' example -----互換模式空間和保持緩衝區的內容。也就是把包含test與check的行互換。
以上執行個體內容摘自網友icyheart的文章,地址是http://www.iteye.com/topic/587673。
八)定時任務。