四虎影院免费观看视频,免费人成黄页网站在线观看国产,男女啪啪免费观看 http://m.inxxote.com/news 提供虛擬主機幫助信息 Mon, 30 Oct 2023 02:58:59 +0000 zh-CN hourly 1 https://wordpress.org/?v=4.1.41 shell腳本編程 linux shell編程實例 http://m.inxxote.com/news/?p=1670 http://m.inxxote.com/news/?p=1670#comments Wed, 13 Dec 2017 09:03:18 +0000 http://m.inxxote.com/news/?p=1670 您好,歡迎來到“C語言中文網-->Shell專題”,您將享受到免費的Shell教程和學習資料!

《Linux命令行與Shell腳本編程大全》第2版 PDF中文版

Shell 誕生于 Unix,是與 Unix/Linux 交互的工具,單獨地學習 Shell 是沒有意義的,請先參考Unix/Linux入門教程,了解 Unix/Lunix 基礎。

近幾年來,Shell一直被忽略,是一個不受重視的腳本語言。Shell雖然是Unix的第一個腳本語言,但它是相當優秀的。它結合了延展性與效率,持續保有獨具的特色,并不斷的被改良,使它多年來能與那些花招很多的腳本語言保持抗衡。

Shell需要依賴其他程序才能完成大部分的工作,這或許是它的缺陷,但它不容置疑的長處是:簡潔的腳本語言標記方式,而且比C語言編寫的程序執行更快、更有效率。

C語言中文網以通俗易懂的語言向您講解Shell編程,讓您在最短的時間內快速掌握Shell,編寫出實用的程序和代碼。

為了讓您盡快體驗最新技術,我們的教程將不斷更新,保持與時俱進,請及時關注。您的支持是我們前進的動力!

說明:C語言中文網的文章由團隊成員翻譯、編輯和整理,難免有錯誤和紕漏,請在文章底部留言向我們指出,謝謝。

Shell腳本編程的常識

 

現在我們使用的操作系統(Windows、Mac OS、Android、iOS 等)都是帶圖形界面的,簡單直觀,容易上手,對專業用戶(程序員、網管等)和普通用戶(家庭主婦、老年人等)都非常適用;計算機的普及離不開圖形界面。

然而在計算機的早期并沒有圖形界面,我們只能通過一個一個地命令來控制計算機,這些命令有成百上千之多,且不說記住這些命令非常困難,每天面對沒有任何色彩的“黑屏”本身就是一件枯燥的事情;這個時候的計算機還遠遠談不上炫酷和普及,只有專業人員才能使用。

圖:早期的電腦,都是“黑紙白字”

猛擊《帶你逛西雅圖活電腦博物館》可以欣賞更多早期的計算機。

對于圖形界面,用戶點擊某個圖標就能啟動某個程序;對于命令行,用戶輸入某個程序的名字(可以看做一個命令)就能啟動某個程序。這兩者的基本過程都是類似的,都需要查找程序在硬盤上的安裝位置,然后將它們加載到內存運行。

關于程序的運行原理,請猛擊《載入內存,讓程序運行起來》。

換句話說,圖形界面和命令行要達到的目的是一樣的,都是讓用戶控制計算機。

然而,真正能夠控制計算機硬件(CPU、內存、顯示器等)的只有操作系統內核(Kernel),圖形界面和命令行只是架設在用戶和內核之間的一座橋梁。

由于安全、復雜、繁瑣等原因,用戶不能直接接觸內核(也沒有必要),需要另外再開發一個程序,讓用戶直接使用這個程序;該程序的作用就是接收用戶的操作(點擊圖標、輸入命令),并進行簡單的處理,然后再傳遞給內核。如此一來,用戶和內核之間就多了一層“代理”,這層“代理”既簡化了用戶的操作,也保護了內核。

用戶界面和命令行就是這個另外開發的程序,就是這層“代理”。在Linux下,這個命令行程序叫做 Shell。

Shell 除了能解釋用戶輸入的命令,將它傳遞給內核,還可以:

  • 調用其他程序,給其他程序傳遞數據或參數,并獲取程序的處理結果;
  • 在多個程序之間傳遞數據,把一個程序的輸出作為另一個程序的輸入;
  • Shell 本身也可以被其他程序調用。


由此可見,Shell 是將內核、程序和用戶連接了起來。

Shell 本身支持的命令并不多,但是它可以調用其他的程序,每個程序就是一個命令,這使得 Shell 命令的數量可以無限擴展,其結果就是 Shell 的功能非常強大,完全能夠勝任 Linux 的日常管理工作,如文本或字符串檢索、文件的查找或創建、大規模軟件的自動部署、更改系統設置、監控服務器性能、發送報警郵件、抓取網頁內容、壓縮文件等。

Shell 并不是簡單的堆砌命令,我們還可以在 Shell 中編程,這和使用 C/C++、Java、Python 等常見的編程語言并沒有什么兩樣。

Shell 雖然沒有 C/C++、Java、Python 等強大,但也支持了基本的編程元素,例如:

  • if...else 選擇結構,switch...case 開關語句,for、while、until 循環;
  • 變量、數組、字符串、注釋、加減乘除、邏輯運算等概念;
  • 函數,包括用戶自定義的函數和內置函數(例如 printf、export、eval 等)。


站在這個角度講,Shell 也是一種編程語言,它的編譯器(解釋器)是 Shell 這個程序。我們平時所說的 Shell,有時候是指連接用戶和內核的這個程序,有時候又是指 Shell 編程。

Shell 主要用來開發一些實用的、自動化的小工具,而不是用來開發具有復雜業務邏輯的中大型軟件,例如檢測計算機的硬件參數、一鍵搭建Web開發環境、日志分析等,Shell 都非常合適。

使用 Shell 的熟練程度反映了用戶對 Linux 的掌握程度,運維工程師、網絡管理員、程序員都應該學習 Shell。

尤其是 Linux 運維工程師,Shell 更是必不可少的,是必須掌握的技能,它使得我們能夠自動化地管理服務器集群,否則你就得一個一個地登錄所有的服務器,對每一臺服務器都進行相同的設置,而這些服務器可能有成百上千之多,會浪費大量的時間在重復性的工作上。

Shell 是一種腳本語言

任何代碼最終都要被“翻譯”成二進制的形式才能在計算機中執行。

有的編程語言,如 C/C++、Pascal、Go語言、匯編等,必須在程序運行之前將所有代碼都翻譯成二進制形式,也就是生成可執行文件,用戶拿到的是最終生成的可執行文件,看不到源碼。

這個過程叫做編譯(Compile),這樣的編程語言叫做編譯型語言,完成編譯過程的軟件叫做編譯器(Compiler)。

而有的編程語言,如 Shell、JavaScript、Python、PHP等,需要一邊執行一邊翻譯,不會生成任何可執行文件,用戶必須拿到源碼才能運行程序。程序運行后會即時翻譯,翻譯完一部分執行一部分,不用等到所有代碼都翻譯完。

這個過程叫做解釋,這樣的編程語言叫做解釋型語言或者腳本語言(Script),完成解釋過程的軟件叫做解釋器。

編譯型語言的優點是執行速度快、對硬件要求低、保密性好,適合開發操作系統、大型應用程序、數據庫等。

腳本語言的優點是使用靈活、部署容易、跨平臺性好,非常適合Web開發以及小工具的制作。

Shell 就是一種腳本語言,我們編寫完源碼后不用編譯,直接運行源碼即可。

(這些往往是經常用到,但是各種網絡上的材料都語焉不詳的東西,個人認為比較有用)

七種文件類型

d??????????? 目錄?????????????????????????????????????????????????????? l???????????? 符號鏈接

s???????????? 套接字文件?????????????????????????????????????????? b??????????? 塊設備文件

c??????????? 字符設備文件?????????????????????????????????????? p??????????? 命名管道文件

-???????????? 普通文件

正則表達式

從一個文件或命令輸出中抽取或過濾文本時??墒褂谜齽t表達式(RE),正則表達式是一些特殊或不很特殊的字符串模式的集合。

基本的元字符集:

^?????????????????? 只匹配行首。

$?????????????????? 只匹配行尾。

*?????????????????? 一個單字符后緊跟*,匹配0個或多個此單字符。

[]?????????????????? 匹配[]內字符,可以是一個單字符,也可以是字符序列??梢允?/p>

用-來表示[]內范圍,如[1-5]等價于[1,2,3,4,5]。

\??????????????????? 屏蔽一個元字符的特殊含義,如\$表示字符$,而不表示匹配行

尾。

.?? ????????????? 匹配任意單字符。

pattern\{n\}?? 匹配pattern出現的次數n

pattern\{n,\}m匹配pattern出現的次數,但表示次數最少為n

pattern\{n,m\} 匹配pattern出現的次數在n與m之間(n,m為0-255)

幾個常見的例子:

顯示可執行的文件:ls –l | grep …x...x..x

只顯示文件夾:ls –l | grep? ^d

匹配所有的空行:^$

匹配所有的單詞:[A-Z a-z]*

匹配任一非字母型字符:[^A-Z a-z]

包含八個字符的行:^……..$(8個.)

字符類描述

以下是可用字符類的相當完整的列表:

[:alnum:] 字母數字 [a-z A-Z 0-9]

[:alpha:] 字母 [a-z A-Z]

[:blank:] 空格或制表鍵

[:cntrl:] 任何控制字符

[:digit:] 數字 [0-9]

[:graph:] 任何可視字符(無空格)

[:lower:] 小寫 [a-z]

[:print:] 非控制字符

[:punct:] 標點字符

[:space:] 空格

[:upper:] 大寫 [A-Z]

[:xdigit:] 十六進制數字 [0-9 a-f A-F]

盡可能使用字符類是很有利的,因為它們可以更好地適應非英語 locale(包括某些必需的重音字符等等).

shell的引號類型

shell共有四種引用類型:

“ ”????????? 雙引號

‘ ’?????????? 單引號

` ` ??????? 反引號

\??????????? 反斜線

l??????? “ ” 可引用除$、` 、\ 、外的任意字符或字符串,“ ”中的變量能夠正常顯示變量值。

l??????? ‘ ’與“ ”類似,不同在于shell會忽略任何的引用值。

例如: GIRL=‘girl’

echo “The ‘$GIRL’ did well”

則打?。篢he ‘girl’ did well

l??????? ` `用于設置系統命令的輸出到變量,shell會將` `中的內容作為一個系統命令并執行質。

例如:echo `date` 則打印當前的系統時間。

l??????? \ 用來屏蔽特殊含義的字符:&? *? +? ^? $? `? “? |? ?

例如:expr 12 \* 12 將輸出144

變量設置時的不同模式:

valiable_name=value?????????? 設置實際值到 variable_name中

valiable_name+value?????????? 如果設置了variable_name,則重設其值

valiable_name:?value?????????? 如果未設置variable_name,則先顯示未定義用戶錯誤信息

valiable_name?value?????????? 如果未設置variable_name,則顯示系統錯誤信息

valiable_name:=value?? 如果未設置variable_name,則設置其值

valiable_name-value??????????? 同上,但取值并不設置到variable_name

條件測試

test命令用于測試字符串、文件狀態和數字,expr測試和執行數值輸出。

Test格式:test condition 或 [ condition ](需要特別注意的是condition的兩邊都要有一個空格,否則會報錯),test命令返回0表示成功。

l??????? 下面將分別描述test的三種測試:

n??????? 文件狀態測試(常用的)

-d?????????? 測試是否文件夾

-f??????????? 測試是否一般文件

-L????????? 測試是否鏈接文件

-r?????????? 測試文件是否可讀

-w ??????? 測試文件是否可寫

-x?????????? 測試文件是否可執行

-s?????????? 測試文件是否非空

n??????? 字符串測試

五種格式: test? “string”

test? string_operator? “string”

test? “string”? string_operator? “string”

[ string_operator? “string” ]

[ “string”? string_operator? “string” ]

其中string_operator可以為:?????? =???? 兩字符串相等

!=??? 兩字符串不等

-z ? 空串

-n ? 非空串

n??????? 數值測試

兩種格式: “number”? number_operator? “number”

[ “number”? number_operator? “number” ]

其中:number_operator 可以為:-eq? 、-ne、-gt、-lt、-ge

例如:? NUMBER=130

[ “990”? –le? “995”? –a? “NUMBER”? -gt? “133” ]

(其中-a表示前后結果相“與”)

l??????? expr命令一般用于整數值,但也可以用于字符串。

n??????? 格式:? expr srgument operator operator argument

例如:? expr 10 + 10

expr 10 ^ 2 (10的平方)

expr $value + 10

n??????? 增量計數――expr在循環中最基本的用法

例如:? LOOP=0

LOOP=`expr $LOOP + 1`

n??????? 模式匹配:通過指定的冒號選項計算字符串中的字符數

例如:? value=account.doc

expr $value : `\(.*\).doc`

輸出 account

每一個在UNIX/Linux上工作的程序員可能都擅長shell腳本編程。但大家解決問題的方式卻不盡相同,這要取決于對專業知識的掌握程度、使用命令的種類、看待問題的方式等等。對于那些處在shell腳本編程初級階段的程序員來說,遵循一些恰當的做法可以幫助你更快、更好的學習這些編程技巧。下面,我們就來討論這些能幫助你學習shell腳本編程的方法吧。

0、多動手

你想學習shell腳本編程,這很不錯。于是你拿了一本書開始學習。一些人會首先通讀整本教材后再上機練習。這種方法可能適用于一些人,但我卻不太看好它。我的建議是,僅僅學一些最基礎的能夠讓你開始編碼的知識就可以了。之后,動手寫一些簡單的程序吧。一旦你由于知識上的欠缺而不得不停止時,再回到書本上去讀你想要了解的那部分,然后繼續做你的項目。如此周而復始,不斷提高你的水平。這種邊學邊做的方法曾讓我受益良多。

1、善用命令提示符

有時候,我們寫的腳本中有一些錯誤。我們修改錯誤,運行腳本,但系統再次報錯。并且這個改錯報錯的過程可能會發生很多次。碰到這些情況,首先需要找到有問題的行或命令,這可以通過一些調試語句來輕松做到。一旦發現這條語句,嘗試在命令提示符下執行相同的語句。如果它在命令提示符下開始正常運行,你就可以容易的推斷出它不能正常運行的原因了??赡苁怯捎谀承╁e誤輸入的命令,或者是某些環境變量不匹配,或者是從不同的地方引用了某個二進制文件等等。這種方法會讓調試變得簡單易行。

關于 shell 腳本編程的10 個最佳實踐

2、考慮問題要全面

現在我們來看個問題。你想到了關于某個問題的解決方案,但這個解決方案只適用于處理小型文件??墒钱斕幚肀容^大的文件時,你該怎么辦?舉個例子,我們想要得到一個文件的第一行內容:

Shell

1
sed -n '1p' file

這條語句當然會給出你想要的第一行內容??墒侨绻幚淼奈募习偃f條記錄呢?盡管上面的那條sed命令可以輸出文件的第一行內容,但是想要處理大型文件一定會帶來性能上的問題。

解決辦法:

Shell

1
sed -n '1p;1q' file

這條命令將只輸出第一行,同時退出程序。

3、經常嘗試不同的方法

你在寫腳本時碰到一個問題,然后你找到了一種獨特的解決方法。下一次你偶然又碰到類似的問題,這時,不要再用以前你用過的方法來解決。試試另外一種方法吧。如果某一天再次遇到這種情況,再試試其它方法。

例如:

Shell

1
2
3
4
if [ $? -eq 0 ]
then
?? echo "Success"
fi

另一種方法:

Shell

1
[ $? -eq 0 ] && echo "Success"

現在你可能會明白這個博客里會有那么多以“……的不同解決方法”為題的文章了吧。所有這些文章的目的都是用來幫助訂閱這個博客的開發者開闊視野,打開思路。

4、快速編碼

腳本可以節省我們的時間,提高生產力??墒牵y道我們花在寫腳本和測試上的時間還少嗎?我們想寫一個腳本,于是打開一個文件,寫下代碼,保存文件,之后運行腳本,系統報錯,我們再打開文件修改、保存、運行……在這個過程中會花費很多時間。在此前的一篇題為《如何快速寫shell腳本》的文章里,你可以學會如何編寫腳本和測試正在運行中的腳本,而不用再回顧命令提示符。這些方法可以加快編碼的速度。當我寫腳本的時候,我總是使用這些方法。而且我可以很肯定的說,它們幫我節約了不少時間。

5、經常使用內部命令

無論碰到哪種情況,請盡量考慮使用內部命令而不是外部命令。在此前的一篇題為《內部命令和外部命令》的文章里,我們可以看到二者間的差異。用內部命令對你永遠都有好處。根據正在處理的輸入文件的大小,內部命令可以在性能方面為你節省很多。雖然你并不總是有這樣選擇內部命令抑或外部命令的機會,但在某些情況下,你一定能做出正確的選擇。

6、沒有必要使用cat命令

這是我們經常在論壇里討論的話題之一。沒有必要使用cat命令指的是在有些時候,我們會發現根本沒有必要使用cat命令。有時候,使用了多余的cat命令會讓你的代碼看起來很丑陋,而且還會帶來性能上的問題。

例如:

Shell

1
$ cat /etc/passwd | grep guru

正確的方法應該是:

Shell

1
$ grep guru /etc/passwd

7、仔細閱讀錯誤信息

程序員常犯的一個錯誤是:當我們敲入的命令報錯后,我們中的大多數人只是對錯誤信息一瞥而過,而不會去認真的讀一讀。很多時候,錯誤信息里就包含了解決辦法。更重要的是,有時候我們修改了某個錯誤并再次運行后,系統依舊會報錯。然后我們再次修改,但系統再次報錯。這可能會持續很長時間。但實際上,舊的錯誤可能已經被糾正,只是由于出現了其它一些新錯誤才導致系統再次報錯。而我們依舊在懷疑為什么修改好的代碼依然不能正常運行。因此,請你養成仔細閱讀錯誤信息的習慣。

8、盡量避免臃腫的命令

你正在嘗試去從一個大的文件中篩選某條信息。接下來你可能寫一大堆命令來實現這一功能??墒?,盡管你將得到正確的結果,你寫的命令卻不夠好,且晦澀難懂。因此,我們應該盡量避免這種情況發生。下面這個例子就是代碼優化的好例子。

從程序員的角度來看, Shell本身是一種用C語言編寫的程序,從用戶的角度來看,Shell是用戶與Linux操作系統溝通的橋梁。用戶既可以輸入命令執行,又可以利用 Shell腳本編程,完成更加復雜的操作。在Linux GUI日益完善的今天,在系統管理等領域,Shell編程仍然起著不可忽視的作用。深入地了解和熟練地掌握Shell編程,是每一個Linux用戶的必修 功課之一。

Linux的Shell種類眾多,常見的有:Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shell(/usr/bin/ksh)、Shell for Root(/sbin/sh),等等。不同的Shell語言的語法有所不同,所以不能交換使用。每種Shell都有其特色之處,基本上,掌握其中任何一種 就足夠了。在本文中,我們關注的重點是Bash,也就是Bourne Again Shell,由于易用和免費,Bash在日常工作中被廣泛使用;同時,Bash也是大多數Linux系統默認的Shell。在一般情況下,人們并不區分 Bourne Shell和Bourne Again Shell,所以,在下面的文字中,我們可以看到#!/bin/sh,它同樣也可以改為#!/bin/bash。

利用vi等文本編輯器編寫Shell腳本的格式是固定的,如下:

?
1
2
3
#!/bin/sh
#comments
Your commands go here

首行中的符號#!告訴系統其后路徑所指定的程序即是解釋此腳本文件的Shell程 序。如果首行沒有這句話,在執行腳本文件的時候,將會出現錯誤。后續的部分就是主程序,Shell腳本像高級語言一樣,也有變量賦值,也有控制語句。除第 一行外,以#開頭的行就是注釋行,直到此行的結束。如果一行未完成,可以在行尾加上",這個符號表明下一行與此行會合并為同一行。

編輯完畢,將腳本存盤為filename.sh,文件名后綴sh表明這是一個Bash腳本文件。執行腳本的時候,要先將腳本文件的屬性改為可執行的:

?
1
chmod +x filename.sh

執行腳本的方法是:

?
1
./filename.sh

下面我們從經典的“hello world”入手,看一看最簡單的Shell腳本的模樣。

?
1
2
3
4
#!/bin/sh
#print hello world in the console window
a = "hello world"
echo $a

Shell Script是一種弱類型語言,使用變量的時候無需首先聲明其類型。新的變量會在本地數據區分配內存進行存儲,這個變量歸當前的Shell所有,任何子進 程都不能訪問本地變量。這些變量與環境變量不同,環境變量被存儲在另一內存區,叫做用戶環境區,這塊內存中的變量可以被子進程訪問。變量賦值的方式是:

?
1
variable_name = variable_value

如果對一個已經有值的變量賦值,新值將取代舊值。取值的時候要在變量名前加$,$variable_name可以在引號中使用,這一點和其他高級語言是明顯不同的。如果出現混淆的情況,可以使用花括號來區分,例如:

echo "Hi, $as"

就不會輸出“Hi, hello worlds”,而是輸出“Hi,”。這是因為Shell把$as當成一個變量,而$as未被賦值,其值為空。正確的方法是:

echo "Hi, ${a}s"

單引號中的變量不會進行變量替換操作。
關于變量,還需要知道幾個與其相關的Linux命令。

env用于顯示用戶環境區中的變量及其取值;set用于顯示本地數據區和用戶環境區中的變量及其取值;unset用于刪除指定變量當前的取值,該值將被指定為NULL;export命令用于將本地數據區中的變量轉移到用戶環境區。

]]>
http://m.inxxote.com/news/?feed=rss2&p=1670 0