什么要使用Shell編程?
Linux操作系統是由UNIX操作系統發展起來的.UNIX操作系統中所體現出來的思想和哲學深沉的影響了現代其他的操作統.在UNIX系統中提供了許多不同的Shell程序.大多數的商業UNIX提供了Korn Shell,當然了我們也還有其他的Shell可以來用.雖然Shell看起來與Windows的命令行相類似,但是他顯得更為的強大,可以以他的方式來運行更為復雜的程序.我們可以使用Shell進行更為快速和簡單的編輯.另外在大多數的Linux基系統的安裝提供了Shell,所以我們可能很方便的來檢測我們的工作是否可以正常的進行工作.而且Shell可以提供許多的實用程序,我們可以用這樣的內容來很好的進行我們的工作,而且這樣的程序易于維護和移植.
一些哲學:
現在我們來認識一下UNIX和Linux哲學.UNIX是建立在代碼高度重用的基礎上的.我們可以建立一個簡單的實用程序,那么其他的人就可以用字符串鏈接或是其他的形式來使用我們的程序.Linux的一大優點就是提供了許多優秀的工具.如:
$ ls -al | more
這個命令使用了ls和more命令,而且使用了管道來重定向輸出.我們可以使用簡單的腳本來創建立大的復雜的程序.
例如,如果我們要打印bash的man手冊頁我們可以用下面的命令:
$ man bash | col -b | lpr
因為Linux的自動文件處理,這些程序的使用者一般并不要知道這些程序是以哪種語言寫成的.
管道和重定向:
在我們詳細的說明Shell編程之前,我們先來說明一下Linux的程序(不僅是Shell程序)如何來重定向輸入和輸出.
重定向輸出:
也許我們已經對輸出重定向較為熟悉了.如:
$ ls -l > lsoutput.txt
這個命令會將ls命令的輸出保存期在一個名為lsoutput.txt的文件中.
然而事實上要有比我們在這個例子中顯示的還要多的重定向.現在我們要知道的就是文件修飾
0是程序的標準的輸入,1為標準輸出,2為標準的錯誤輸出
.我們可以獨立的重定向這些中的任何一個.事實上我們也可以重定向其他的文件修飾,但是一般的情況下為0,1,2.
在上面的這個例子中,我們使用>修飾符來重定向標準輸出到一個文件.在默認的情況,如果這個文件已經存在了,他就會被重寫.
如果要增加文件內容,我們可以使用>>運算符.如:
$ ps >> lsoutput.txt
這個就會在文件后面增加新的輸出內容.
如果要重定向標準錯誤輸出,我們可以使用>運算符和我們要使用的文件修飾符來進行重定向.因為標準的錯誤輸出修飾符為2,我們就可以使用2>運算符.這在忽略錯誤信息而又不顯示在屏幕上時就會顯得尤為有用.
假如我們要在腳本中使用kill命令來殺掉一個進程,然而卻是常用這樣的情況,在這個命令運行之前這個進程已經不存在了.如果是這樣的情況,kill命令就會產生一個標準的錯誤輸出,而在默認的情況下,這個輸出要顯示在屏幕上.通過重定向輸出和錯誤,我們就可以阻止在屏幕上顯示任何內容.如下面的命令:
$ kill -HUP 1234 >killout.txt 2>killerr.txt
這個命令就會將輸出和錯誤信息存放在一個單獨的文件中.
如果我們要將這兩個輸出放在一個文件中,我們可以使用>&來組合這兩種輸出.如:
$ kill -1 1234 >killouterr.txt 2>&1
這個命令就可以將所有的輸出放在同一個文件中.在這里我們要注意的就是命令的順序.這個命令的順序可以解釋為重定向標準輸出到文件killouterr.然后重定向標準錯誤輸出到與標準輸出同一的地方.如果我們弄錯了順序,我們就不會得到我們希望的輸出.
在這里我們會看到kill命令的結果使用了返回代碼,然而常常是我們并不需要保存標準輸出或是標準錯誤輸出.我們可以使用UNIX中的/dev/null來忽略所有的錯誤輸出.如:
$ kill -1 1234 >/dev/null 2>&1
重定向輸入:
與重定向輸出相類似,我們也可以重定向輸入.如:
$ more < killout.txt
管道:
我們可以使用管道符|來連接進程.在Linux系統中,由管道連接起來的進程可以自動運行,就如同在他們有一個數據流一樣.在下面的這個例子中,我們要使用sort命令來排序ps的輸出.而如果我們不使用管道,我們就要分幾步來完成:
$ ps > psout.txt
$ sort psout.txt >pssort.out
一個更好的辦法就是可以用管道來處理:
$ ps | sort > pssort.out
因為我們要在屏幕上看到他們,我們要使用第三個進程:
$ ps | sort | more
使用的管道數并沒有一個量的限制.如果我們要看到正在運行的除了shell以外的不同名字的進程,我們可以用下面的命令:
$ ps -xo comm | sort | uniq | grep -v sh | more
在這個命令中,使用了ps的輸出,將這個輸出以字母的順序進行排序,使用uniq來解壓進程,使用grep -v sh來移除名為sh的進程,最后在屏幕上顯示結果.
在這里我們就可以看到,這樣的方式式要比單個執行的命令好得多.在這里我們要注意的一點點就是,在這個命令中我們不要兩次使用同一個文件.如下面的命令:
$ cat mydate.txt | sort | uniq | >mydate.txt
這樣我們就會得到一個空文件,因為在我們讀取這個之前已經改寫了這個文件.
Shell作為編程語言:
現在我們已經知道了一些基本的Shell操作,下面我們就進入腳本編程.有兩種寫Shell程序的方法:我們可以輸入命令隊列,讓Shell來交互的執行他們,或者是將這些命令存放在一個文件中,然后作為程序進行調用.
交互程序:
在命令行輸入腳本是可以快速方便的試出小的代碼段,如果我們正在學習或是進行測試這是一個相當好的方式.假如我們有許多的C文件,而我們希望找出其中含有POSIX字符串的文件.我們可以如下面的樣子進行整體的操作:
$ for file in *
> do
> if grep -l POSIX $file
> then
> more $file
> fi
> done
在這里我們就會看到Shell提示符由$變成了>.我們可以輸入命令由Shell來決定如何時停止并且立即執行腳本程序.
在這個例子中,grep命令查找其中含有POSIX字符串的文件,然后more將這個文件中的內容打印在屏幕上.最后Shell返回提示符.
Shell也會允許我們使用通配符進行擴展.我們可以使用*來匹配字符串,我們還可以使用?來匹配單個的字符,而[set]可以允許檢測在這里列出的任何一個單個字符.[^set]則正好相反,要除去在這里所列出的字符.我們還可以使用花括號{}進行擴展,這可以允許我們將任意的字符串放在一起.如下面的例子:
$ ls my_{finger,toe}s
這個命令會列出文件my_fingers,my_toes.
有經驗的用戶也許會用一種更有效率的方式來運行這些命令.也許我們會使用下面的命令:
$ more `grep -l POSIX *`
或者是下面的命令:
$ more $(grep -l POSIX *)
$ grep -l POSIX * | more
這些命令都會打印出含有POSIX的文件名.
然而事實上如果我們每一次要完成這樣的任務就要輸入一系列命令的做法是相當麻煩的一件事.我們需要就是將這些命令放在一個文件中,作為一個Shell腳本來引用,這樣就可以在我們需要的時候來運行他了.
創建一個腳本:
首先我們可以使用任何一個我們喜歡的文本編輯來創建一個含有下面命令的文件,命名為first:
#!/bin/bash
#first
#This file looks through all the files in the current
#directory for the string POSIX, and then prints the names of
#those files to the standard output.
for file in *
do
if grep -q POSIX $file
then
echo $file
fi
done
exit 0
在這個文件中以#開始的行被看作是注釋,在通常的情況下,我們會將#放在第一列.在這里我們要注意的是第一行的注釋,#!/bash/bash是一個特殊格式的注釋.#!后面的字符告訴系統我們要執行這個文件的程序.在當前的情況下,/bin/bash是默認的Shell程序.
在這里指定的絕對路徑最好的做法就是要少于32個字符,因為在一些老版本的UNIX系統有著這樣的限制,我們這樣做可以很好的做到向后兼容.
因為這個腳本被看作是標準的Shell輸入,所以可以包含任何的Linux命令.
exit命令可以返回一個較為敏感的退出代碼.如果這個程序是單獨運行的,我們就沒有必要來檢測這個程序的返回代碼,而如果我們要在另一個程序中進行調用,進行返回代碼的檢測以確定這個程序是否成功執行就顯得尤為重要.雖然有時我們并不希望我們的程序被其他的程序調用,我們也要返回一個合理的代碼.因為也許有一天我們的程序就會作為其他腳本的一部分而被重用.
0則表明這個程序成功執行.因為腳本并不會檢測任何的失敗,所以我們總是返回成功代碼.
我們要注意的另外一點就是在這個文件中我們并沒有使用任何的擴展名或是前綴.在Linux或是UNIX系統中并不依靠文件的擴展名來判斷文件的類型.如果我們希望可以為這個文件加一個.sh或是其他的擴展名,但是Shell并不會在意這些.大多數預先安裝的腳本并沒有擴展名,而最好的用來檢測文件類型的辦法就是使用file命令.
使用腳本可執行:
現在我們就有了我們的腳本程序,我們可以用兩種方式來運行.最簡單的辦法就是將腳本文件作為參數使用Shell進行調用:
$ /bin/bash first
這樣就可以正常的工作了.如果我們可以將其與其他的Linux命令相分離而是直接輸入命令文件名就可以運行這個程序就顯得更好一些.如果我們要這樣的做,我們首先要使用下面的命令來為他加上可執行屬性:
$ chmod +x first
現在我們就可以用下面的命令來運行了:
$ ./first
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
