BASH

最簡(jiǎn)單的例子 —— Hello World!

關(guān)于輸入、輸出和錯(cuò)誤輸出

BASH 中對(duì)變量的規(guī)定(與 C 語(yǔ)言的異同)

BASH 中的基本流程控制語(yǔ)法

函數(shù)的使用

2.1???? 最簡(jiǎn)單的例子 —— Hello World!

幾乎所有的講解編程的書給讀者的第一個(gè)例子都是 Hello World 程序悟耘,那么我們今天也就從這個(gè)例子出發(fā)儿倒,來(lái)逐步了解 BASH。

用 vi 編輯器編輯一個(gè) hello 文件如下:

#!/bin/bash

# This is a very simple example

echo Hello World

這樣最簡(jiǎn)單的一個(gè) BASH 程序就編寫完了其骄。這里有幾個(gè)問(wèn)題需要說(shuō)明一下:

一,第一行的 #! 是什么意思

二,第一行的 /bin/bash 又是什么意思

三屁桑,第二行是注釋嗎

四,echo 語(yǔ)句

五栏赴,如何執(zhí)行該程序

#! 是說(shuō)明 hello 這個(gè)文件的類型的蘑斧,有點(diǎn)類似于 Windows 系統(tǒng)下用不同文件后綴來(lái)表示不同文件類型的意思(但不相同)。Linux 系統(tǒng)根據(jù) "#!" 及該字串后面的信息確定該文件的類型,關(guān)于這一問(wèn)題同學(xué)們回去以后可以通過(guò) "man magic"命令 及 /usr/share/magic 文件來(lái)了解這方面的更多內(nèi)容乌叶。在 BASH 中 第一行的 "#!" 及后面的 "/bin/bash" 就表明該文件是一個(gè) BASH 程序盆偿,需要由 /bin 目錄下的 bash 程序來(lái)解釋執(zhí)行。BASH 這個(gè)程序一般是存放在 /bin 目錄下准浴,如果你的 Linux 系統(tǒng)比較特別事扭,bash 也有可能被存放在 /sbin 、/usr/local/bin 乐横、/usr/bin 求橄、/usr/sbin 或 /usr/local/sbin 這樣的目錄下;如果還找不到葡公,你可以用 "locate bash" "find / -name bash 2> /dev/null" 或 "whereis bash" 這三個(gè)命令找出 bash 所在的位置罐农;如果仍然找不到,那你可能需要自己動(dòng)手安裝一個(gè) BASH 軟件包了催什。

第二行的 "# This is a ..." 就是 BASH 程序的注釋涵亏,在 BASH 程序中從“#”號(hào)(注意:后面緊接著是“!”號(hào)的除外)開始到行尾的多有部分均被看作是程序的注釋。的三行的 echo 語(yǔ)句的功能是把 echo 后面的字符串輸出到標(biāo)準(zhǔn)輸出中去蒲凶。由于 echo 后跟的是 "Hello World" 這個(gè)字符串气筋,因此 "Hello World"這個(gè)字串就被顯示在控制臺(tái)終端的屏幕上了。需要注意的是 BASH 中的絕大多數(shù)語(yǔ)句結(jié)尾處都沒(méi)有分號(hào)旋圆。

如何執(zhí)行該程序呢宠默?有兩種方法:一種是顯式制定 BASH 去執(zhí)行:

bashhello或bashhello或sh hello (這里 sh 是指向 bash 的一個(gè)鏈接,“l(fā)rwxrwxrwx 1 root root 4 Aug 20 05:41 /bin/sh -> bash”)

或者可以先將 hello 文件改為可以執(zhí)行的文件灵巧,然后直接運(yùn)行它搀矫,此時(shí)由于 hello 文件第一行的 "#! /bin/bash" 的作用,系統(tǒng)會(huì)自動(dòng)用/bin/bash 程序去解釋執(zhí)行 hello 文件的:

chmodu+xhellochmodu+xhello./hello

此處沒(méi)有直接 “$ hello”是因?yàn)楫?dāng)前目錄不是當(dāng)前用戶可執(zhí)行文件的默認(rèn)目錄刻肄,而將當(dāng)前目錄“.”設(shè)為默認(rèn)目錄是一個(gè)不安全的設(shè)置瓤球。

需要注意的是,BASH 程序被執(zhí)行后肄方,實(shí)際上 Linux 系統(tǒng)是另外開設(shè)了一個(gè)進(jìn)程來(lái)運(yùn)行的冰垄。

2.2???? 關(guān)于輸入、輸出和錯(cuò)誤輸出

在字符終端環(huán)境中权她,標(biāo)準(zhǔn)輸入/標(biāo)準(zhǔn)輸出的概念很好理解虹茶。輸入即指對(duì)一個(gè)應(yīng)用程序 或命令的輸入,無(wú)論是從鍵盤輸入還是從別的文件輸入隅要;輸出即指應(yīng)用程序或命令產(chǎn)生的一些信息蝴罪;與 Windows 系統(tǒng)下不同的是,Linux 系統(tǒng)下還有一個(gè)標(biāo)準(zhǔn)錯(cuò)誤輸出的概念步清,這個(gè)概念主要是為程序調(diào)試和系統(tǒng)維護(hù)目的而設(shè)置的要门,錯(cuò)誤輸出于標(biāo)準(zhǔn)輸出分開可以讓一些高級(jí)的錯(cuò)誤信息不干擾正常的輸出 信息虏肾,從而方便一般用戶的使用。

在 Linux 系統(tǒng)中:標(biāo)準(zhǔn)輸入(stdin)默認(rèn)為鍵盤輸入欢搜;標(biāo)準(zhǔn)輸出(stdout)默認(rèn)為屏幕輸出封豪;標(biāo)準(zhǔn)錯(cuò)誤輸出(stderr)默認(rèn)也是輸出到屏幕(上面的 std 表示 standard)。在 BASH 中使用這些概念時(shí)一般將標(biāo)準(zhǔn)輸出表示為 1炒瘟,將標(biāo)準(zhǔn)錯(cuò)誤輸出表示為 2吹埠。下面我們舉例來(lái)說(shuō)明如何使用他們,特別是標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤輸出疮装。

輸入缘琅、輸出及標(biāo)準(zhǔn)錯(cuò)誤輸出主要用于 I/O 的重定向,就是說(shuō)需要改變他們的默認(rèn)設(shè)置廓推。先看這個(gè)例子:

ls>lsresultls>lsresultls -l >> ls_result

上面這兩個(gè)命令分別將 ls 命令的結(jié)果輸出重定向到 ls_result 文件中和追加到 ls_result 文件中刷袍,而不是輸出到屏幕上。">"就是輸出(標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤輸出)重定向的代表符號(hào)樊展,連續(xù)兩個(gè) ">" 符號(hào)呻纹,即 ">>" 則表示不清除原來(lái)的而追加輸出。下面再來(lái)看一個(gè)稍微復(fù)雜的例子:

$ find /home -name lost* 2> err_result

這個(gè)命令在 ">" 符號(hào)之前多了一個(gè) "2"滚局,"2>" 表示將標(biāo)準(zhǔn)錯(cuò)誤輸出重定向居暖。由于 /home 目錄下有些目錄由于權(quán)限限制不能訪問(wèn)顽频,因此會(huì)產(chǎn)生一些標(biāo)準(zhǔn)錯(cuò)誤輸出被存放在 err_result 文件中藤肢。大家可以設(shè)想一下?find /home -name lost* 2>>err_result 命令會(huì)產(chǎn)生什么結(jié)果?

如果直接執(zhí)行 find /home -name lost* > all_result 糯景,其結(jié)果是只有標(biāo)準(zhǔn)輸出被存入 all_result 文件中嘁圈,要想讓標(biāo)準(zhǔn)錯(cuò)誤輸出和標(biāo)準(zhǔn)輸入一樣都被存入到文件中,那該怎么辦呢蟀淮?看下面這個(gè)例子:

$ find /home -name lost* > all_result 2>& 1

上面這個(gè)例子中將首先將標(biāo)準(zhǔn)錯(cuò)誤輸出也重定向到標(biāo)準(zhǔn)輸出中最住,再將標(biāo)準(zhǔn)輸出重定向到 all_result 這個(gè)文件中。這樣我們就可以將所有的輸出都存儲(chǔ)到文件中了怠惶。為實(shí)現(xiàn)上述功能涨缚,還有一種簡(jiǎn)便的寫法如下:

$ find /home -name lost* >& all_result

如果那些出錯(cuò)信息并不重要,下面這個(gè)命令可以讓你避開眾多無(wú)用出錯(cuò)信息的干擾:

$?find /home -name lost* 2> /dev/null

同學(xué)們回去后還可以再試驗(yàn)一下如下幾種重定向方式策治,看看會(huì)出什么結(jié)果脓魏,為什么?

find?/home?-name?lost*?>?all_result?1>&?2find?/home?-name?lost*?>?all_result?1>&?2find /home -name lost* 2> all_result 1>& 2

$ find /home -name lost* 2>& 1 > all_result

另外一個(gè)非常有用的重定向操作符是?"-"通惫,請(qǐng)看下面這個(gè)例子:

$ (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xvfp -)

該命令表示把 /source/directory 目錄下的所有文件通過(guò)壓縮和解壓茂翔,快速的全部移動(dòng)到 /dest/directory 目錄下去,這個(gè)命令在 /source/directory 和 /dest/directory 不處在同一個(gè)文件系統(tǒng)下時(shí)將顯示出特別的優(yōu)勢(shì)履腋。

下面還幾種不常見的用法:

n<&- 表示將 n 號(hào)輸入關(guān)閉

<&- 表示關(guān)閉標(biāo)準(zhǔn)輸入(鍵盤)

n>&- 表示將 n 號(hào)輸出關(guān)閉

>&- 表示將標(biāo)準(zhǔn)輸出關(guān)閉

2.3???? BASH 中對(duì)變量的規(guī)定(與 C 語(yǔ)言的異同)

好了下面我們進(jìn)入正題珊燎,先看看 BASH 中的變量是如何定義和使用的惭嚣。對(duì)于熟悉 C 語(yǔ)言的程序員,我們將解釋 BASH 中的定義和用法與 C 語(yǔ)言中有何不同悔政。

2.3.1. BASH 中的變量介紹

我們先來(lái)從整體上把握一下 BASH 中變量的用法晚吞,然后再去分析 BASH 中變量使用與 C 語(yǔ)言中的不同。BASH 中的變量都是不能含有保留字谋国,不能含有 "-" 等保留字符载矿,也不能含有空格。

2.3.1.1 簡(jiǎn)單變量

在 BASH 中變量定義是不需要的烹卒,沒(méi)有 "int i" 這樣的定義過(guò)程闷盔。如果想用一個(gè)變量,只要他沒(méi)有在前面被定義過(guò)旅急,就直接可以用逢勾,當(dāng)然你使用該變量的第一條語(yǔ)句應(yīng)該是對(duì)他賦初值了,如果你不賦初值也沒(méi)關(guān) 系藐吮,只不過(guò)該變量是空( 注意:是 NULL溺拱,不是 0 )。不給變量賦初值雖然語(yǔ)法上不反對(duì)谣辞,但不是一個(gè)好的編程習(xí)慣迫摔。好了我們看看下面的例子:

首先用 vi 編輯下面這個(gè)文件 hello2:

#!/bin/bash

# give the initialize value to STR

STR="Hello World"

echo $STR

在上面這個(gè)程序中我們需要注意下面幾點(diǎn):

一,變量賦值時(shí)泥从,'='左右兩邊都不能有空格句占;

二,BASH 中的語(yǔ)句結(jié)尾不需要分號(hào)(";")躯嫉;

三纱烘,除了在變量賦值和在FOR循環(huán)語(yǔ)句頭中,BASH 中的變量使用必須在變量前加"$"符號(hào)祈餐,同學(xué)們可以將上面程序中第三行改為 "echo STR" 再試試擂啥,看看會(huì)出什么結(jié)果。==>output: STR

四帆阳,由于 BASH 程序是在一個(gè)新的進(jìn)程中運(yùn)行的哺壶,所以該程序中的變量定義和賦值不會(huì)改變其他進(jìn)程或原始 Shell 中同名變量的值,也不會(huì)影響他們的運(yùn)行蜒谤。

更細(xì)致的文檔甚至提到以但引號(hào)括起來(lái)的變量將不被 BASH 解釋為變量山宾,如?'STR′,而被看成為純粹的字符串芭逝。而且更為標(biāo)準(zhǔn)的變量引用方式是STR′塌碌,而被看成為純粹的字符串旬盯。而且更為標(biāo)準(zhǔn)的變量引用方式是{STR} 這樣的台妆,STR自不過(guò)是對(duì)STR自不過(guò)是對(duì){STR} 的一種簡(jiǎn)化切厘。在復(fù)雜情況下(即有可能產(chǎn)生歧義的地方)最好用帶 {} 的表示方式。

BASH 中的變量既然不需要定義途蒋,也就沒(méi)有類型一說(shuō)宽堆,一個(gè)變量即可以被定義為一個(gè)字符串,也可以被再定義為整數(shù)乙帮。如果對(duì)該變量進(jìn)行整數(shù)運(yùn)算峡捡,他就被解釋為整數(shù)装盯;如果對(duì)他進(jìn)行字符串操作,他就被看作為一個(gè)字符串壤玫。請(qǐng)看下面的例子:

#!/bin/bash

x=1999

let "x =x+1"echox+1"echox

x="olympic'"xechoxechox

關(guān)于整數(shù)變量計(jì)算豁护,有如下幾種:"?+ - * / % ",他們的意思和字面意思相同欲间。整數(shù)運(yùn)算一般通過(guò) let 和 expr 這兩個(gè)指令來(lái)實(shí)現(xiàn)楚里,如對(duì)變量 x 加 1 可以寫作:let"x = $x + 1"或者?x=`expr $x + 1`

在比較操作上,整數(shù)變量和字符串變量各不相同猎贴,詳見下表:


比如:

比較字符串 a 和 b 是否相等就寫作:if [a=a=b ]

判斷字符串 a 是否為空就寫作:?if [ -za]判斷整數(shù)變量a是否大于b就寫作:if[a]判斷整數(shù)變量a是否大于b就寫作:if[a -gt $b ]

更細(xì)致的文檔推薦在字符串比較時(shí)盡量不要使用 -n 班缎,而用 ! -z 來(lái)代替。(其中符號(hào) "!" 表示求反操作)

BASH 中的變量除了用于對(duì) 整數(shù) 和 字符串 進(jìn)行操作以外她渴,另一個(gè)作用是作為文件變量达址。BASH 是 Linux 操作系統(tǒng)的 Shell,因此系統(tǒng)的文件必然是 BASH 需要操作的重要對(duì)象趁耗,如?if [ -x /root ] 可以用于判斷 /root 目錄是否可以被當(dāng)前用戶進(jìn)入沉唠。下表列出了 BASH 中用于判斷文件屬性的操作符:


注意:上表中的 file 及 file1、file2 都是指某個(gè)文件或目錄的路徑苛败。

2.3.1.1. 關(guān)于局部變量

在 BASH 程序中如果一個(gè)變量被使用了满葛,那么直到該程序的結(jié)尾径簿,該變量都一直有效。為了使得某個(gè)變量存在于一個(gè)局部程序塊中纱扭,就引入了局部變量的概念牍帚。BASH 中,在變量首次被賦初值時(shí)加上 local 關(guān)鍵字就可以聲明一個(gè)局部變量乳蛾,如下面這個(gè)例子:

#!/bin/bash

HELLO=Hello

function hello {

local HELLO=World

echoHELLO??}??echoHELLO??}??echoHELLO

hello

echo $HELLO

該程序的執(zhí)行結(jié)果是:

Hello

World

Hello

這個(gè)執(zhí)行結(jié)果表明全局變量HELLO的值在執(zhí)行函數(shù)hello時(shí)并沒(méi)有被改變暗赶。也就是說(shuō)局部變量HELLO的值在執(zhí)行函數(shù)hello時(shí)并沒(méi)有被改變。也就是說(shuō)局部變量HELLO 的影響只存在于函數(shù)那個(gè)程序塊中肃叶。

2.3.2. BASH 中的變量與 C 語(yǔ)言中變量的區(qū)別

這里我們?yōu)樵瓉?lái)不熟悉 BASH 編程蹂随,但是非常熟悉 C 語(yǔ)言的程序員總結(jié)一下在 BASH 環(huán)境中使用變量需要注意的問(wèn)題。

1因惭,BASH 中的變量在引用時(shí)都需要在變量前加上 ""符號(hào)(第一次賦值及在For循環(huán)的頭部不用加""符號(hào)(第一次賦值及在For循環(huán)的頭部不用加""符號(hào) )岳锁;

2,BASH 中沒(méi)有浮點(diǎn)運(yùn)算蹦魔,因此也就沒(méi)有浮點(diǎn)類型的變量可用激率;

3,BASH 中的整形變量的比較符號(hào)與 C 語(yǔ)言中完全不同勿决,而且整形變量的算術(shù)運(yùn)算也需要經(jīng)過(guò) let 或 expr 語(yǔ)句來(lái)處理乒躺;

2.4???? BASH 中的基本流程控制語(yǔ)法

BASH 中幾乎含有 C 語(yǔ)言中常用的所有控制結(jié)構(gòu),如條件分支低缩、循環(huán)等嘉冒,下面逐一介紹。

2.4.1 if...then...else

if 語(yǔ)句用于判斷和分支咆繁,其語(yǔ)法規(guī)則和 C 語(yǔ)言的 if 非常相似讳推。其幾種基本結(jié)構(gòu)為:

if [ expression ]

then

statments

fi

或者

if [ expression ]

then

statments

else

statments

fi

或者

if [ expression ]

then

statments

else if [ expression ]

then

statments

else

statments

fi

或者

if [ expression ]

then

statments

elif [ expression ]

then

statments

else

statments

fi

值得說(shuō)明的是如果你將 if 和 then 簡(jiǎn)潔的寫在一行里面,就必須在 then 前面加上分號(hào)玩般,如:if [ expression ]; then ... 银觅。下面這個(gè)例子說(shuō)明了如何使用 if 條件判斷語(yǔ)句:

#!/bin/bash

if [1?gt90]thenecho"Good,1?gt90]thenecho"Good,1"

elif [1?gt70]thenecho"OK,1?gt70]thenecho"OK,1"

else

echo "Bad, $1"

fi

exit 0

上面例子中的 $1 是指命令行的第一個(gè)參數(shù),這個(gè)會(huì)在后面的“BASH 中的特殊保留字”中講解壤短。

2.4.2 for

for 循環(huán)結(jié)構(gòu)與 C 語(yǔ)言中有所不同设拟,在 BASH 中 for 循環(huán)的基本結(jié)構(gòu)是:

for $var in

do

statments

done

其中 $var 是循環(huán)控制變量,

是var需要遍歷的一個(gè)集合久脯,do/done對(duì)包含了循環(huán)體,相當(dāng)于C語(yǔ)言中的一對(duì)大括號(hào)镰吆。另外如果do和for被寫在同一行帘撰,必須在do前面加上";"。如:forvar需要遍歷的一個(gè)集合万皿,do/done對(duì)包含了循環(huán)體摧找,相當(dāng)于C語(yǔ)言中的一對(duì)大括號(hào)核行。另外如果do和for被寫在同一行,必須在do前面加上";"蹬耘。如:forvar in?; do 芝雪。下面是一個(gè)運(yùn)用 for 進(jìn)行循環(huán)的例子:

#!/bin/bash

for day in Sun Mon Tue Wed Thu Fri Sat

do

echoday??done???#?如果列表被包含在一對(duì)雙引號(hào)中,則被認(rèn)為是一個(gè)元素??for?day?in?"Sun?Mon?Tue?Wed?Thu?Fri?Sat"??do??echoday??done???#?如果列表被包含在一對(duì)雙引號(hào)中综苔,則被認(rèn)為是一個(gè)元素??for?day?in?"Sun?Mon?Tue?Wed?Thu?Fri?Sat"??do??echoday

done

exit 0

注意上面的例子中惩系,在 for 所在那行的變量 day 是沒(méi)有加 ""符號(hào)的,而在循環(huán)體內(nèi)如筛,echo所在行變量"符號(hào)的堡牡,而在循環(huán)體內(nèi),echo所在行變量day 是必須加上 "$" 符號(hào)的杨刨。另外如果寫成 for day 而沒(méi)有后面的 in

部分晤柄,則 day 將取遍命令行的所有參數(shù)。如這個(gè)程序:

#!/bin/bash

for param

do

echo $param

done

exit 0

上面這個(gè)程序?qū)⒘谐鏊忻钚袇?shù)妖胀。for 循環(huán)結(jié)構(gòu)的循環(huán)體被包含在 do/done 對(duì)中芥颈,這也是后面的 while、until 循環(huán)所具有的特點(diǎn)赚抡。

2.4.3 while

while 循環(huán)的基本結(jié)構(gòu)是:

while [ condition ]

do

statments

done

這個(gè)結(jié)構(gòu)請(qǐng)大家自己編寫一個(gè)例子來(lái)驗(yàn)證爬坑。

2.4.4 until

until 循環(huán)的基本結(jié)構(gòu)是:

until [ condition is TRUE ]

do

statments

done

這個(gè)結(jié)構(gòu)也請(qǐng)大家自己編寫一個(gè)例子來(lái)驗(yàn)證。

2.4.5 case

BASH 中的 case 結(jié)構(gòu)與 C 語(yǔ)言中的 switch 語(yǔ)句的功能比較類似怕品,可以用于進(jìn)行多項(xiàng)分支控制妇垢。其基本結(jié)構(gòu)是:

case "$var" in

condition1 )

statments1;;

condition2 )

statments2;;

...

* )

default statments;;

esac

下面這個(gè)程序是運(yùn)用 case 結(jié)構(gòu)進(jìn)行分支執(zhí)行的例子:

#!/bin/bash

echo "Hit a key, then hit return."

read Keypress

case "$Keypress" in

[a-z] ) echo "Lowercase letter";;

[A-Z] ) echo "Uppercase letter";;

[0-9] ) echo "Digit";;

* ) echo "Punctuation, whitespace, or other";;

esac

exit 0

上面例子中的第四行 "read Keypress" 一句中的 read 語(yǔ)句表示從鍵盤上讀取輸入。這個(gè)命令將在本講義的?BASH 的其他高級(jí)問(wèn)題中講解肉康。

2.4.6 break/continue

熟悉 C 語(yǔ)言編程的都很熟悉 break 語(yǔ)句和 continue 語(yǔ)句闯估。BASH 中同樣有這兩條語(yǔ)句,而且作用和用法也和 C 語(yǔ)言中相同吼和,break 語(yǔ)句可以讓程序流程從當(dāng)前循環(huán)體中完全跳出涨薪,而 continue 語(yǔ)句可以跳過(guò)當(dāng)次循環(huán)的剩余部分并直接進(jìn)入下一次循環(huán)。

2.5???? 函數(shù)的使用

BASH 是一個(gè)相對(duì)簡(jiǎn)單的腳本語(yǔ)言炫乓,不過(guò)為了方便結(jié)構(gòu)化的設(shè)計(jì)刚夺,BASH 中也提供了函數(shù)定義的功能。BASH 中的函數(shù)定義很簡(jiǎn)單末捣,只要向下面這樣寫就可以了:

function my_funcname {

code block

}

或者

my_funcname() {

code block

}

上面的第二種寫法更接近于 C 語(yǔ)言中的寫法侠姑。BASH 中要求函數(shù)的定義必須在函數(shù)使用之前,這是和 C 語(yǔ)言用頭文件說(shuō)明函數(shù)方法的不同箩做。

更進(jìn)一步的問(wèn)題是如何給函數(shù)傳遞參數(shù)和獲得返回值莽红。BASH 中函數(shù)參數(shù)的定義并不需要在函數(shù)定義處就制定,而只需要在函數(shù)被調(diào)用時(shí)用 BASH 的保留變量112 ... 來(lái)引用就可以了;BASH 的返回值可以用 return 語(yǔ)句來(lái)指定返回一個(gè)特定的整數(shù)安吁,如果沒(méi)有 return 語(yǔ)句顯式的返回一個(gè)返回值醉蚁,則返回值就是該函數(shù)最后一條語(yǔ)句執(zhí)行的結(jié)果(一般為 0,如果執(zhí)行失敗返回錯(cuò)誤碼)鬼店。函數(shù)的返回值在調(diào)用該函數(shù)的程序體中通過(guò) $? 保留字來(lái)獲得网棍。下面我們就來(lái)看一個(gè)用函數(shù)來(lái)計(jì)算整數(shù)平方的例子:

#!/bin/bash

square() {

let "res =1?1?1"

returnres??}???squareres??}???square1

result=?echo?echoresult

exit 0

BASH 中的特殊保留字

保留變量

隨機(jī)數(shù)

運(yùn)算符

變量的特殊操作

3.1???? 保留變量

BASH 中有一些保留變量,下面列出了一些:

IFS這個(gè)變量中保存了用于分割輸入?yún)?shù)的分割字符妇智,默認(rèn)識(shí)空格滥玷。IFS這個(gè)變量中保存了用于分割輸入?yún)?shù)的分割字符,默認(rèn)識(shí)空格俘陷。HOME  這個(gè)變量中存儲(chǔ)了當(dāng)前用戶的根目錄路徑罗捎。

PATH這個(gè)變量中存儲(chǔ)了當(dāng)前Shell的默認(rèn)路徑字符串。PATH這個(gè)變量中存儲(chǔ)了當(dāng)前Shell的默認(rèn)路徑字符串拉盾。PS1  表示第一個(gè)系統(tǒng)提示符桨菜。

PS2表示的二個(gè)系統(tǒng)提示符。PS2表示的二個(gè)系統(tǒng)提示符捉偏。PWD  表示當(dāng)前工作路徑倒得。

EDITOR表示系統(tǒng)的默認(rèn)編輯器名稱。EDITOR表示系統(tǒng)的默認(rèn)編輯器名稱夭禽。BASH  表示當(dāng)前 Shell 的路徑字符串美莫。

0,0,1,2,...表示系統(tǒng)傳給腳本程序或腳本程序傳給函數(shù)的第0個(gè)苛谷、第一個(gè)碉克、第二個(gè)等參數(shù)醉顽。2,...表示系統(tǒng)傳給腳本程序或腳本程序傳給函數(shù)的第0個(gè)、第一個(gè)潮梯、第二個(gè)等參數(shù)骗灶。#   表示腳本程序的命令參數(shù)個(gè)數(shù)或函數(shù)的參數(shù)個(gè)數(shù)。

$$   表示該腳本程序的進(jìn)程號(hào)秉馏,常用于生成文件名唯一的臨時(shí)文件耙旦。

$?   表示腳本程序或函數(shù)的返回狀態(tài)值,正常為 0萝究,否則為非零的錯(cuò)誤號(hào)免都。

$*   表示所有的腳本參數(shù)或函數(shù)參數(shù)。

$@   和 $* 涵義相似帆竹,但是比 $* 更安全绕娘。

$!   表示最近一個(gè)在后臺(tái)運(yùn)行的進(jìn)程的進(jìn)程號(hào)。

3.2????隨機(jī)數(shù)

隨機(jī)數(shù)是經(jīng)常要用到的栽连,BASH 中也提供了這個(gè)功能业舍,請(qǐng)看下面這個(gè)程序:

#!/bin/bash

# Prints different random integer from 1 to 65536

a=RANDOMechoRANDOMechoa

exit 0

這個(gè)程序可以在每次執(zhí)行的時(shí)候隨機(jī)的打印出一個(gè)大小在?1 到 65536?之間的整數(shù)。

3.3???? 運(yùn)算符

算術(shù)運(yùn)算符

+ - * / % 表示加減乘除和取余運(yùn)算

+= -= *= /= 同 C 語(yǔ)言中的含義

位操作符

<< <<= >> >>= 表示位左右移一位操作

& &= | |= 表示按位與升酣、位或操作

~ ! 表示非操作

^ ^= 表示異或操作

關(guān)系運(yùn)算符

< > <= >= == != 表示大于舷暮、小于、大于等于噩茄、小于等于下面、等于、不等于操作

&& || 邏輯與绩聘、邏輯或操作

3.4???? 變量的特殊操作

BASH 中還有一些對(duì)變量的簡(jiǎn)潔沥割、快速的操作,大家還記得 "var"和"var"和"var" 同樣是對(duì)變量的引用吧凿菩,對(duì)var進(jìn)行一些變化就可以產(chǎn)生一些新功能:var進(jìn)行一些變化就可以產(chǎn)生一些新功能:{var-default} 表示如果變量var還沒(méi)有設(shè)置机杜,則保持var還沒(méi)有設(shè)置,則保持var 沒(méi)有設(shè)置的狀態(tài)衅谷,并返回后面的默認(rèn)值 default椒拗。

var=default表示如果變量var=default表示如果變量var 還沒(méi)有設(shè)置,則取后面的默認(rèn)值 default获黔。

var+otherwise表示如果變量var+otherwise表示如果變量var 已經(jīng)設(shè)置蚀苛,則返回 otherwise 的值,否則返回空( null )玷氏。

var?errmsg表示如果變量var?errmsg表示如果變量var 已經(jīng)設(shè)置堵未,則返回該變量的值,否則將后面的 err_msg 輸出到標(biāo)準(zhǔn)錯(cuò)誤輸出上盏触。

請(qǐng)同學(xué)們自己嘗試下面的例子:

#!/bin/bash

echo ${var?There is an error}

exit 0

還有下面一些用法渗蟹,這些用法主要用于從文件路徑字符串中提取有用信息:

{var#pattern},{var#pattern},{var##pattern} 用于從變量var中剝?nèi)プ疃蹋ㄗ铋L(zhǎng))的和pattern相匹配的最左側(cè)的串。var中剝?nèi)プ疃蹋ㄗ铋L(zhǎng))的和pattern相匹配的最左側(cè)的串赞辩。{var%pattern},{var%%pattern}?用于從變量{var%%pattern}?用于從變量var 中剝?nèi)プ疃蹋ㄗ铋L(zhǎng))的和 pattern 相匹配的最右側(cè)的串雌芽。

另外BASH 2中還加入下面一些操作:

var:pos表示去掉變量var:pos表示去掉變量var 中前 pos 個(gè)字符。

var:pos:len表示變量var:pos:len表示變量var 中去掉前 pos 個(gè)字符后的剩余字符串的前 len 個(gè)字符诗宣。

var/pattern/replacement表示將變量var/pattern/replacement表示將變量var 中第一個(gè)出現(xiàn)的 pattern 模式替換為 replacement 字符串膘怕。

var//pattern/replacement表示將變量var//pattern/replacement表示將變量var 中出現(xiàn)的所有 pattern 模式全部都替換為 replacment 字符串。

BASH 中的其他高級(jí)問(wèn)題

BASH 中對(duì)返回值的處理

用 BASH 設(shè)計(jì)簡(jiǎn)單用戶界面

在 BASH 中讀取用戶輸入

一些特殊的慣用法

BASH 程序的調(diào)試

關(guān)于 BASH2

4.1???? BASH 中對(duì)返回值的處理

無(wú)論是在 Shell 中對(duì) BASH 腳本返回值的處理召庞,還是在腳本中對(duì)函數(shù)返回值的處理岛心,都是通過(guò) "$?" 系統(tǒng)變量來(lái)獲得。BASH 要求返回值必須為一個(gè)整數(shù)篮灼,不能用 return 語(yǔ)句返回字符串變量忘古。

4.2???? 用 BASH 設(shè)計(jì)簡(jiǎn)單用戶界面

BASH 中提供了一個(gè)小的語(yǔ)句格式,可以讓程序快速的設(shè)計(jì)出一個(gè)字符界面的用戶交互選擇的菜單诅诱,該功能就是由 select 語(yǔ)句來(lái)實(shí)現(xiàn)的髓堪,select 語(yǔ)句的語(yǔ)法為:

select var in

do

statments use $var

done

上面的語(yǔ)法結(jié)構(gòu)在執(zhí)行后,BASH 會(huì)將

中的所有項(xiàng)加上數(shù)字列在屏幕上等待用戶選擇,在用戶作出選擇后干旁,變量 $var 中就包含了那個(gè)被選中的字符串驶沼,然后就可以對(duì)該變量進(jìn)行需要的操作了。我們可以從下面的例子中更直觀的來(lái)理解這個(gè)功能:

#!/bin/bash

OPTIONS="Hello Quit"

select opt inOPTIONS;doif["OPTIONS;doif["opt" = "Quit" ]; then

echo done

exit

elif [ "$opt" = "Hello" ]; then

echo Hello World

else

clear

echo bad option

fi

done

exit 0

大家可以試著執(zhí)行上面的程序争群,看看是什么執(zhí)行結(jié)果回怜。

4.3???? 在 BASH 中讀取用戶輸入

BASH 中通過(guò) read 函數(shù)來(lái)實(shí)現(xiàn)讀取用戶輸入的功能,如下面這段程序:

#!/bin/bash

echo Please enter your name

read NAME

echo "Hi! $NAME !"

exit 0

上面這個(gè)腳本讀取用戶的輸入换薄,并回顯在屏幕上。

另外 BASH 中還提供另外一種稱為?here documents 的結(jié)構(gòu)????复旬,可以將用戶需要通過(guò)鍵盤輸入的字符串改為從程序體中直接讀入驹碍,如密碼。下面的小程序演示了這個(gè)功能:

#!/bin/bash

passwd="aka@tsinghua"

ftp -n localhost <

user anonymous $passwd

binary

bye

FTPFTP

exit 0

這個(gè)程序在用戶需要通過(guò)鍵盤敲入一些字符時(shí)洽损,通過(guò)程序內(nèi)部的動(dòng)作來(lái)模擬鍵盤輸入。請(qǐng)注意 here documents 的基本結(jié)構(gòu)為:

command <

statments

...

SOMESPECIALSTRING

這里要求在需要鍵盤輸入的命令后延刘,直接加上 <<符號(hào)碘赖,然后跟上一個(gè)特別的字符串普泡,在該串后按順序輸入本來(lái)應(yīng)該由鍵盤輸入的所有字符撼班,在所有需要輸入的字符都結(jié)束后砰嘁,重復(fù)一遍前面 <<符號(hào)后的“特別的字符串”即表示該輸入到此結(jié)束。

4.4 一些特殊的慣用法

在 BASH 中 () 一對(duì)括號(hào)一般被用于求取括號(hào)中表達(dá)式的值或命令的執(zhí)行結(jié)果斟冕,如:(a=hello; echo $a) 宫静,其作用相當(dāng)于 `...` 伏伯。

: 有兩個(gè)含義说搅,一是表示空語(yǔ)句适肠,有點(diǎn)類似于 C 語(yǔ)言中的單個(gè) ";" 。表示該行是一個(gè)空命令逛揩,如果被用在 while/until 的頭結(jié)構(gòu)中辩稽,則表示值 0,會(huì)使循環(huán)一直進(jìn)行下去从媚,如下例:

while :

do

operation-1

operation-2

...

operation-n

done

另外 : 還可以用于求取后面變量的值,比如:

#!/bin/bash

:HOSTNAME?USER?MAIL?echoHOSTNAME?USER?MAIL?echoHOSTNAME

echoUSERechoUSERechoMAIL

exit 0

在 BASH 中 export 命令用于將系統(tǒng)變量輸出到外層的 Shell 中了喷众。

4.5 BASH 程序的調(diào)試

用?bash -x bash-script 命令,可以查看一個(gè)出錯(cuò)的 BASH 腳本到底錯(cuò)在什么地方侮腹,可以幫助程序員找出腳本中的錯(cuò)誤。

另外用 trap 語(yǔ)句可以在 BASH 腳本出錯(cuò)退出時(shí)打印出一些變量的值稻励,以供程序員檢查父阻。trap 語(yǔ)句必須作為繼 "#!/bin/bash" 后的第一句非注釋代碼,一般 trap 命令被寫作:?trap 'messagecheckvar1checkvar1checkvar2' EXIT 。

4.6 關(guān)于 BASH2

使用 bash -version 命令可以看出當(dāng)前你正在使用的 BASH 是什么版本毁腿,一般版本號(hào)為1.14或其他版本。而現(xiàn)在機(jī)器上一般還安裝了一個(gè)版本號(hào)為 2.0 的 BASH 妓羊。該 BASH 也在 /bin 目錄下裕循。BASH2 提供了一些新功能,有興趣的同敘可以自己去看相關(guān)資料净刮,或直接 man bash2 即可剥哑。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市淹父,隨后出現(xiàn)的幾起案子株婴,更是在濱河造成了極大的恐慌,老刑警劉巖弹灭,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件督暂,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡穷吮,警方通過(guò)查閱死者的電腦和手機(jī)逻翁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)捡鱼,“玉大人八回,你說(shuō)我怎么就攤上這事〖菡” “怎么了缠诅?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)乍迄。 經(jīng)常有香客問(wèn)我管引,道長(zhǎng),這世上最難降的妖魔是什么闯两? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任褥伴,我火速辦了婚禮谅将,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘重慢。我一直安慰自己饥臂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布似踱。 她就那樣靜靜地躺著隅熙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪核芽。 梳的紋絲不亂的頭發(fā)上囚戚,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音狞洋,去河邊找鬼弯淘。 笑死,一個(gè)胖子當(dāng)著我的面吹牛吉懊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播假勿,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼借嗽,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了转培?” 一聲冷哼從身側(cè)響起恶导,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎浸须,沒(méi)想到半個(gè)月后惨寿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡删窒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年裂垦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肌索。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蕉拢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出诚亚,到底是詐尸還是另有隱情晕换,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布站宗,位于F島的核電站闸准,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏梢灭。R本人自食惡果不足惜夷家,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一蒸其、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瘾英,春花似錦枣接、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至湿蛔,卻和暖如春膀曾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背阳啥。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工添谊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人察迟。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓斩狱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親扎瓶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子所踊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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