《Linux命令行與shell腳本編程大全》第11章筆記(下)

本篇內(nèi)容均摘自《Linux命令行與shell腳本編程大全》慎陵,個(gè)人認(rèn)為需要重點(diǎn)學(xué)習(xí)的章節(jié)副渴。【免費(fèi)】Linux命令行與Shell腳本編程大全 第3版 PDF全本 21MB 百度網(wǎng)盤下載 - 今夕是何夕 - 博客園

重定向輸入和輸出
有些時(shí)候你想要保存某個(gè)命令的輸出而不僅僅只是讓它顯示在顯示器上空繁。 bash shell提供了幾個(gè)操作符府喳,可以將命令的輸出重定向到另一個(gè)位置(比如文件)窗声。重定向可以用于輸入,也可以用于輸出厌衙,可以將文件重定向到命令輸入距淫。本節(jié)介紹了如何在shell腳本中使用重定向。
11.5.1 輸出重定向
最基本的重定向?qū)⒚畹妮敵霭l(fā)送到一個(gè)文件中婶希。 bash shell用大于號(hào)( >)來(lái)完成這項(xiàng)功能:command > outputfile
之前顯示器上出現(xiàn)的命令輸出會(huì)被保存到指定的輸出文件中榕暇。

$ date > test6
$ ls -l test6
-rw-r--r-- 1 user user 29 Feb 10 17:56 test6
$ cat test6
Thu Feb 10 17:56:58 EDT 2014

重定向操作符創(chuàng)建了一個(gè)文件test6(通過(guò)默認(rèn)的umask設(shè)置),并將date命令的輸出重定向到該文件中喻杈。如果輸出文件已經(jīng)存在了彤枢,重定向操作符會(huì)用新的文件數(shù)據(jù)覆蓋已有文件。

$ who > test6
$ cat test6
user pts/0 Feb 10 17:55

現(xiàn)在test6文件的內(nèi)容就是who命令的輸出筒饰。有時(shí)堂污,你可能并不想覆蓋文件原有內(nèi)容,而是想要將命令的輸出追加到已有文件中龄砰,比如你正在創(chuàng)建一個(gè)記錄系統(tǒng)上某個(gè)操作的日志文件盟猖。在這種情況下,可以用雙大于號(hào)( >>)來(lái)追加數(shù)據(jù)换棚。

$ date >> test6
$ cat test6
user pts/0 Feb 10 17:55
Thu Feb 10 18:02:14 EDT 2014

test6文件仍然包含早些時(shí)候who命令的數(shù)據(jù)式镐,現(xiàn)在又加上了來(lái)自date命令的輸出。


輸入重定向
輸入重定向和輸出重定向正好相反固蚤。輸入重定向?qū)⑽募膬?nèi)容重定向到命令,而非將命令的輸出重定向到文件娘汞。輸入重定向符號(hào)是小于號(hào)( <):
command < inputfile
一個(gè)簡(jiǎn)單的記憶方法就是:在命令行上,命令總是在左側(cè)夕玩,而重定向符號(hào)“指向”數(shù)據(jù)流動(dòng)的方向你弦。小于號(hào)說(shuō)明數(shù)據(jù)正在從輸入文件流向命令。這里有個(gè)和wc命令一起使用輸入重定向的例子燎孟。

$ wc < test6
2 11 60

wc命令可以對(duì)對(duì)數(shù)據(jù)中的文本進(jìn)行計(jì)數(shù)禽作。默認(rèn)情況下,它會(huì)輸出3個(gè)值:
1.文本的行數(shù)揩页。2. 文本的詞數(shù)旷偿。3.文本的字節(jié)數(shù)。
通過(guò)將文本文件重定向到wc命令,你立刻就可以得到文件中的行萍程、詞和字節(jié)的計(jì)數(shù)幢妄。這個(gè)例子說(shuō)明test6文件有2行、 11個(gè)單詞以及60字節(jié)茫负。還有另外一種輸入重定向的方法蕉鸳,稱為內(nèi)聯(lián)輸入重定向( inline input redirection)。這種方法無(wú)需使用文件進(jìn)行重定向忍法,只需要在命令行中指定用于輸入重定向的數(shù)據(jù)就可以了置吓。乍看一眼,這可能有點(diǎn)奇怪缔赠,但有些應(yīng)用會(huì)用到這種方式(參見11.7節(jié))。內(nèi)聯(lián)輸入重定向符號(hào)是遠(yuǎn)小于號(hào)( <<)友题。除了這個(gè)符號(hào)嗤堰,你必須指定一個(gè)文本標(biāo)記來(lái)劃分輸入數(shù)據(jù)的開始和結(jié)尾。任何字符串都可作為文本標(biāo)記度宦,但在數(shù)據(jù)的開始和結(jié)尾文本標(biāo)記必須一致踢匣。

command << marker
data
marker

在命令行上使用內(nèi)聯(lián)輸入重定向時(shí), shell會(huì)用PS2環(huán)境變量中定義的次提示符(參見第6章)來(lái)提示輸入數(shù)據(jù)戈抄。下面是它的使用情況离唬。

$ wc << EOF
> test string 1
> test string 2
> test string 3
> EOF
3 9 42

次提示符會(huì)持續(xù)提示,以獲取更多的輸入數(shù)據(jù)划鸽,直到你輸入了作為文本標(biāo)記的那個(gè)字符串输莺。wc命令會(huì)對(duì)內(nèi)聯(lián)輸入重定向提供的數(shù)據(jù)進(jìn)行行、詞和字節(jié)計(jì)數(shù)裸诽。


管道
和命令替換所用的反引號(hào)( `)一樣嫂用,管道符號(hào)在shell編程之外也很少用到。該符號(hào)由兩個(gè)豎線構(gòu)成丈冬,一個(gè)在另一個(gè)上面嘱函。然而管道符號(hào)的印刷體通常看起來(lái)更像是單個(gè)豎線( |)埂蕊。在美式鍵盤上往弓,它通常和反斜線( \)位于同一個(gè)鍵。管道被放在命令之間蓄氧,將一個(gè)命令的輸出重定向到另一個(gè)命令中:
command1 | command2
不要以為由管道串起的兩個(gè)命令會(huì)依次執(zhí)行函似。 Linux系統(tǒng)實(shí)際上會(huì)同時(shí)運(yùn)行這兩個(gè)命令,在系統(tǒng)內(nèi)部將它們連接起來(lái)喉童。在第一個(gè)命令產(chǎn)生輸出的同時(shí)缴淋,輸出會(huì)被立即送給第二個(gè)命令。數(shù)據(jù)傳輸不會(huì)用到任何中間文件或緩沖區(qū)。例如:

$ rpm -qa | sort | more

這行命令序列會(huì)先執(zhí)行rpm命令重抖,將它的輸出通過(guò)管道傳給sort命令露氮,然后再將sort的輸出通過(guò)管道傳給more命令來(lái)顯示,在顯示完一屏信息后停下來(lái)钟沛。到目前為止畔规,管道最流行的用法之一是將命令產(chǎn)生的大量輸出通過(guò)管道傳送給more命令。ls -l命令產(chǎn)生了目錄中所有文件的長(zhǎng)列表恨统。對(duì)包含大量文件的目錄來(lái)說(shuō)叁扫,這個(gè)列表會(huì)相當(dāng)長(zhǎng)。通過(guò)將輸出管道連接到more命令畜埋,可以強(qiáng)制輸出在一屏數(shù)據(jù)顯示后停下來(lái)莫绣。


執(zhí)行數(shù)學(xué)運(yùn)算
在shell腳本中有兩種途徑來(lái)進(jìn)行數(shù)學(xué)運(yùn)算。
expr 命令
最開始悠鞍, Bourne shell提供了一個(gè)特別的命令用來(lái)處理數(shù)學(xué)表達(dá)式对室。 expr命令允許在命令行上處理數(shù)學(xué)表達(dá)式,但是特別笨拙咖祭。

$ expr 1 + 5
6

(個(gè)人備注:實(shí)際上我試的時(shí)候1和+掩宜,還有5之間沒(méi)有空格,輸出來(lái)是以下的結(jié)果:)

expr 1+5
1+5

盡管標(biāo)準(zhǔn)操作符在expr命令中工作得很好么翰,但在腳本或命令行上使用它們時(shí)仍有問(wèn)題出現(xiàn)牺汤。許多expr命令操作符在shell中另有含義(比如星號(hào))。當(dāng)它們出現(xiàn)在在expr命令中時(shí)浩嫌,會(huì)得到一些詭異的結(jié)果檐迟。

$ expr 5 * 2
expr: syntax error

要解決這個(gè)問(wèn)題码耐,對(duì)于那些容易被shell錯(cuò)誤解釋的字符锅减,在它們傳入expr命令之前伐坏,需要使用shell的轉(zhuǎn)義字符(反斜線)將其標(biāo)出來(lái)。

$ expr 5 \* 2
10

在shell腳本中使用expr命令也同樣復(fù)雜:

$ cat test6
#!/bin/bash
# An example of using the expr command
var1=10
var2=20
var3=$(expr $var2 / $var1)
echo The result is $var3

要將一個(gè)數(shù)學(xué)算式的結(jié)果賦給一個(gè)變量桦沉,需要使用命令替換來(lái)獲取expr命令的輸出:

$ chmod u+x test6
$ ./test6
The result is 2

使用方括號(hào)
bash shell為了保持跟Bourne shell的兼容而包含了expr命令每瞒,但它同樣也提供了一種更簡(jiǎn)單的方法來(lái)執(zhí)行數(shù)學(xué)表達(dá)式。在bash中纯露,在將一個(gè)數(shù)學(xué)運(yùn)算結(jié)果賦給某個(gè)變量時(shí),可以用美元符和方括號(hào)( $[ operation ])將數(shù)學(xué)表達(dá)式圍起來(lái)埠褪。

$ var1=$[1 + 5]
$ echo $var1
6
$ var2=$[$var1 * 2]
$ echo $var2
12

用方括號(hào)執(zhí)行shell數(shù)學(xué)運(yùn)算比用expr命令方便很多挤庇。這種技術(shù)也適用于shell腳本。

$ cat test7
#!/bin/bash
var1=100
var2=50
var3=45
var4=$[$var1 * ($var2 - $var3)]
echo The final result is $var4

運(yùn)行這個(gè)腳本會(huì)得到如下輸出贷掖。

$ chmod u+x test7
$ ./test7
The final result is 500

同樣嫡秕,注意在使用方括號(hào)來(lái)計(jì)算公式時(shí),不用擔(dān)心shell會(huì)誤解乘號(hào)或其他符號(hào)苹威。 shell知道它不是通配符,因?yàn)樗诜嚼ㄌ?hào)內(nèi)掷酗。在bash shell腳本中進(jìn)行算術(shù)運(yùn)算會(huì)有一個(gè)主要的限制。請(qǐng)看下例:

$ cat test8
#!/bin/bash
var1=100
var2=45
var3=$[$var1 / $var2]
echo The final result is $var3

現(xiàn)在泻轰,運(yùn)行一下,看看會(huì)發(fā)生什么:

$ chmod u+x test8
$ ./test8
The final result is 2

bash shell數(shù)學(xué)運(yùn)算符只支持整數(shù)運(yùn)算浮声。若要進(jìn)行任何實(shí)際的數(shù)學(xué)計(jì)算,這是一個(gè)巨大的限制。
浮點(diǎn)解決方案
有幾種解決方案能夠克服bash中數(shù)學(xué)運(yùn)算的整數(shù)限制雳锋。最常見的方案是用內(nèi)建的bash計(jì)算器,叫作bc玷过。

  1. bc的基本用法
    bash計(jì)算器實(shí)際上是一種編程語(yǔ)言,它允許在命令行中輸入浮點(diǎn)表達(dá)式辛蚊,然后解釋并計(jì)算該表達(dá)式,最后返回結(jié)果袋马。 bash計(jì)算器能夠識(shí)別:數(shù)字(整數(shù)和浮點(diǎn)數(shù)),變量(簡(jiǎn)單變量和數(shù)組),注釋(以#或C語(yǔ)言中的/* */開始的行),表達(dá)式,編程語(yǔ)句(例如if-then語(yǔ)句),函數(shù)÷橇荩可以在shell提示符下通過(guò)bc命令訪問(wèn)bash計(jì)算器。要退出bash計(jì)算器桑谍,你必須輸入quit。浮點(diǎn)運(yùn)算是由內(nèi)建變量scale控制的锣披。必須將這個(gè)值設(shè)置為你希望在計(jì)算結(jié)果中保留的小數(shù)位數(shù)贿条,否則無(wú)法得到期望的結(jié)果增热。
$ bc -q
3.44 / 5
0
scale=4
3.44 / 5
.6880
quit

scale變量的默認(rèn)值是0。在scale值被設(shè)置前钓葫, bash計(jì)算器的計(jì)算結(jié)果不包含小數(shù)位。在將其值設(shè)置成4后础浮, bash計(jì)算器顯示的結(jié)果包含四位小數(shù)帆调。 -q命令行選項(xiàng)可以不顯示bash計(jì)算器冗長(zhǎng)的歡迎信息。除了普通數(shù)字豆同, bash計(jì)算器還能支持變量番刊。

$ bc -q
var1=10
var1 * 4
40
var2 = var1 / 5
print var2
2
quit

變量一旦被定義,你就可以在整個(gè)bash計(jì)算器會(huì)話中使用該變量了影锈。 print語(yǔ)句允許你打印變量和數(shù)字芹务。

  1. 在腳本中使用bc
    現(xiàn)在你可能想問(wèn)bash計(jì)算器是如何在shell腳本中幫助處理浮點(diǎn)運(yùn)算的。還記得命令替換嗎鸭廷?是的枣抱,可以用命令替換運(yùn)行bc命令,并將輸出賦給一個(gè)變量辆床。基本格式如下:variable=$(echo "options; expression" | bc)轿秧。第一部分options允許你設(shè)置變量咨堤。如果你需要不止一個(gè)變量菇篡,可以用分號(hào)將其分開一喘。expression參數(shù)定義了通過(guò)bc執(zhí)行的數(shù)學(xué)表達(dá)式。這里有個(gè)在腳本中這么做的例子凸克。
$ cat test9
#!/bin/bash
var1=$(echo "scale=4; 3.44 / 5" | bc)
echo The answer is $var1

這個(gè)例子將scale變量設(shè)置成了四位小數(shù),并在expression部分指定了特定的運(yùn)算咪鲜。運(yùn)行這個(gè)腳本會(huì)產(chǎn)生如下輸出撞鹉。

$ chmod u+x test9
$ ./test9
The answer is .6880

也可以用shell腳本中定義好的變量疟丙。

$ cat test10
#!/bin/bash
var1=100
var2=45
var3=$(echo "scale=4; $var1 / $var2" | bc)
echo The answer for this is $var3

腳本定義了兩個(gè)變量,它們都可以用在expression部分览祖,然后發(fā)送給bc命令炊琉。別忘了用美元符表示的是變量的值而不是變量自身展蒂。這個(gè)腳本的輸出如下苔咪。

$ ./test10
The answer for this is 2.2222

當(dāng)然,一旦變量被賦值团赏,那個(gè)變量也可以用于其他運(yùn)算。

$ cat test11
#!/bin/bash
var1=20
var2=3.14159
var3=$(echo "scale=4; $var1 * $var1" | bc)
var4=$(echo "scale=4; $var3 * $var2" | bc)
echo The final result is $var4

這個(gè)方法適用于較短的運(yùn)算丝里,但有時(shí)你會(huì)涉及更多的數(shù)字体谒。如果需要進(jìn)行大量運(yùn)算杯聚,在一個(gè)命令行中列出多個(gè)表達(dá)式就會(huì)有點(diǎn)麻煩抒痒。有一個(gè)方法可以解決這個(gè)問(wèn)題。 bc命令能識(shí)別輸入重定向纷捞,允許你將一個(gè)文件重定向到bc命令來(lái)處理痢虹。但這同樣會(huì)叫人頭疼,因?yàn)槟氵€得將表達(dá)式存放到文件中惨缆。最好的辦法是使用內(nèi)聯(lián)輸入重定向,它允許你直接在命令行中重定向數(shù)據(jù)坯墨。在shell腳本中病往,你可以將輸出賦給一個(gè)變量捣染。

variable=$(bc << EOF
options
statements
expressions
EOF
)

EOF文本字符串標(biāo)識(shí)了內(nèi)聯(lián)重定向數(shù)據(jù)的起止停巷。記住榕栏,仍然需要命令替換符號(hào)將bc命令的輸賦給變量±俑鳎現(xiàn)在可以將所有bash計(jì)算器涉及的部分都放到同一個(gè)腳本文件的不同行。下面是在腳本中使用這種技術(shù)的例子式曲。

$ cat test12
#!/bin/bash
var1=10.46
var2=43.67
var3=33.2
var4=71
var5=$(bc << EOF
scale = 4
a1 = ( $var1 * $var2)
b1 = ($var3 * $var4)
a1 + b1
EOF
)
echo The final answer for this mess is $var5

將選項(xiàng)和表達(dá)式放在腳本的不同行中可以讓處理過(guò)程變得更清晰兰伤,提高易讀性医清。 EOF字符串標(biāo)識(shí)了重定向給bc命令的數(shù)據(jù)的起止会烙。 當(dāng)然柏腻, 必須用命令替換符號(hào)標(biāo)識(shí)出用來(lái)給變量賦值的命令五嫂。你還會(huì)注意到肯尺,在這個(gè)例子中则吟,你可以在bash計(jì)算器中賦值給變量氓仲。這一點(diǎn)很重要:在bash計(jì)算器中創(chuàng)建的變量只在bash計(jì)算器中有效敬扛,不能在shell腳本中使用啥箭。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末急侥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子豌拙,更是在濱河造成了極大的恐慌题暖,老刑警劉巖胧卤,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異压汪,居然都是意外死亡古瓤,警方通過(guò)查閱死者的電腦和手機(jī)落君,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門皮获,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)魔市,“玉大人赵哲,你說(shuō)我怎么就攤上這事君丁』婷疲” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)法竞。 經(jīng)常有香客問(wèn)我岔霸,道長(zhǎng)呆细,這世上最難降的妖魔是什么絮爷? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任梨树,我火速辦了婚禮渊涝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己厌处,他們只是感情好阔涉,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布瑰排。 她就那樣靜靜地躺著椭住,像睡著了一般。 火紅的嫁衣襯著肌膚如雪宅广。 梳的紋絲不亂的頭發(fā)上跟狱,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天套腹,我揣著相機(jī)與錄音资铡,去河邊找鬼笤休。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的闹啦。 我是一名探鬼主播窍奋,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼江场,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼窖逗!你這毒婦竟也來(lái)了碎紊?” 一聲冷哼從身側(cè)響起音同,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤痴鳄,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后螺句,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛇尚,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡取劫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年谱邪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惦银。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片末誓。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡喇澡,死狀恐怖晴玖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情宪萄,我是刑警寧澤拜英,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布居凶,位于F島的核電站藤抡,受9級(jí)特大地震影響缠黍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜语泽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一踱卵、第九天 我趴在偏房一處隱蔽的房頂上張望惋砂。 院中可真熱鬧,春花似錦、人聲如沸鳞芙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)谢澈。三九已至御板,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钉答。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工数尿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留右蹦,地道東北人何陆。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓甲献,卻偏偏與公主長(zhǎng)得像晃洒,于是被迫代替她去往敵國(guó)和親球及。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吃引,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,367評(píng)論 0 5
  • 本篇內(nèi)容均摘自《Linux命令行與shell腳本編程大全》并思,個(gè)人認(rèn)為需要重點(diǎn)學(xué)習(xí)的章節(jié)宋彼∫羯簦【免費(fèi)】Linux命令行與...
    生信start_site閱讀 1,241評(píng)論 1 4
  • 一、Python簡(jiǎn)介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡(jiǎn)介】: Python 是一個(gè)...
    _小老虎_閱讀 5,720評(píng)論 0 10
  • 內(nèi)容使用多個(gè)命令創(chuàng)建腳本文件顯示消息使用變量輸入輸出重定向管道數(shù)學(xué)運(yùn)算退出腳本 使用多個(gè)命令 如果多個(gè)命令一起使用...
    王詩(shī)翔閱讀 1,955評(píng)論 0 15
  • 第 2 章 SHELL 基礎(chǔ)知識(shí)2.1 shell腳本我們?cè)谏厦婧?jiǎn)單介紹了一下什么是shell腳本,現(xiàn)在我們來(lái)進(jìn)一...
    LiWei_9e4b閱讀 1,553評(píng)論 0 0