欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Bash 實(shí)例,第 2 部分

2000 年 4 月 01 日

在前一篇 bash 的介紹性文章中,Daniel Robbins 為您講解了腳本語(yǔ)言的一些基本元素和使用 bash 的原因。在本文(即第二部分)中,Daniel 繼續前一篇的內容,并講解條件 (if-then) 語(yǔ)句、循環(huán)和更多的 bash 基本結構。

我們先看一下處理命令行自變量的簡(jiǎn)單技巧,然后再看看 bash 基本編程結構。

接收自變量

介紹性文章 中的樣本程序中,我們使用環(huán)境變量 "$1" 來(lái)引用第一個(gè)命令行自變量。類(lèi)似地,可以使用 "$2"、"$3" 等來(lái)引用傳遞給腳本的第二和第三個(gè)自變量。這里有一個(gè)例子:

 #!/usr/bin/env bash                    echo name of script is $0                    echo first argument is $1                    echo second argument is $2                    echo seventeenth argument is $17                    echo number of arguments is $#                    

除以下兩個(gè)細節之外,此例無(wú)需說(shuō)明。第一,"$0" 將擴展成從命令行調用的腳本名稱(chēng),"$#" 將擴展成傳遞給腳本的自變量數目。試驗以上腳本,通過(guò)傳遞不同類(lèi)型的命令行自變量來(lái)了解其工作原理。

有時(shí)需要一次引用 所有 命令行自變量。針對這種用途,bash 實(shí)現了變量 "$@",它擴展成所有用空格分開(kāi)的命令行參數。在本文稍后的 "for" 循環(huán)部分中,您將看到使用該變量的例子。





回頁(yè)首


Bash 編程結構

如果您曾用過(guò)如 C、Pascal、Python 或 Perl 那樣的過(guò)程語(yǔ)言編程,則一定熟悉 "if" 語(yǔ)句和 "for" 循環(huán)那樣的標準編程結構。對于這些標準結構的大多數,Bash 有自己的版本。在下幾節中,將介紹幾種 bash 結構,并演示這些結構和您已經(jīng)熟悉的其它編程語(yǔ)言中結構的差異。如果以前編程不多,也不必擔心。我提供了足夠的信息和示例,使您可以跟上本文的進(jìn)度。





回頁(yè)首


方便的條件語(yǔ)句

如果您曾用 C 編寫(xiě)過(guò)與文件相關(guān)的代碼,則應該知道:要比較特定文件是否比另一個(gè)文件新需要大量工作。那是因為 C 沒(méi)有任何內置語(yǔ)法來(lái)進(jìn)行這種比較,必須使用兩個(gè) stat() 調用和兩個(gè) stat 結構來(lái)進(jìn)行手工比較。相反,bash 內置了標準文件比較運算符,因此,確定“/tmp/myfile 是否可讀”與查看“$myvar 是否大于 4”一樣容易。

下表列出最常用的 bash 比較運算符。同時(shí)還有如何正確使用每一選項的示例。示例要跟在 "if" 之后。例如:

 if [ -z "$myvar" ]                    then                    echo "myvar is not defined"                    fi                    

運算符 描述 示例
文件比較運算符
-e filename 如果 filename存在,則為真 [ -e /var/log/syslog ]
-d filename 如果 filename為目錄,則為真 [ -d /tmp/mydir ]
-f filename 如果 filename為常規文件,則為真 [ -f /usr/bin/grep ]
-L filename 如果 filename為符號鏈接,則為真 [ -L /usr/bin/grep ]
-r filename 如果 filename可讀,則為真 [ -r /var/log/syslog ]
-w filename 如果 filename可寫(xiě),則為真 [ -w /var/mytmp.txt ]
-x filename 如果 filename可執行,則為真 [ -L /usr/bin/grep ]
filename1-nt filename2 如果 filename1filename2新,則為真 [ /tmp/install/etc/services -nt /etc/services ]
filename1-ot filename2 如果 filename1filename2舊,則為真 [ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比較運算符 (請注意引號的使用,這是防止空格擾亂代碼的好方法)
-z string 如果 string長(cháng)度為零,則為真 [ -z "$myvar" ]
-n string 如果 string長(cháng)度非零,則為真 [ -n "$myvar" ]
string1= string2 如果 string1string2相同,則為真 [ "$myvar" = "one two three" ]
string1!= string2 如果 string1string2不同,則為真 [ "$myvar" != "one two three" ]
算術(shù)比較運算符
num1-eq num2 等于 [ 3 -eq $mynum ]
num1-ne num2 不等于 [ 3 -ne $mynum ]
num1-lt num2 小于 [ 3 -lt $mynum ]
num1-le num2 小于或等于 [ 3 -le $mynum ]
num1-gt num2 大于 [ 3 -gt $mynum ]
num1-ge num2 大于或等于 [ 3 -ge $mynum ]

有時(shí),有幾種不同方法來(lái)進(jìn)行特定比較。例如,以下兩個(gè)代碼段的功能相同:

 if [ "$myvar" -eq 3 ]                    then                    echo "myvar equals 3"                    fi                    if [ "$myvar" = "3" ]                    then                    echo "myvar equals 3"                    fi                    

上面兩個(gè)比較執行相同的功能,但是第一個(gè)使用算術(shù)比較運算符,而第二個(gè)使用字符串比較運算符。





回頁(yè)首


字符串比較說(shuō)明

大多數時(shí)候,雖然可以不使用括起字符串和字符串變量的雙引號,但這并不是好主意。為什么呢?因為如果環(huán)境變量中恰巧有一個(gè)空格或制表鍵,bash 將無(wú)法分辨,從而無(wú)法正常工作。這里有一個(gè)錯誤的比較示例:

 if [ $myvar = "foo bar oni" ]                    then                    echo "yes"                    fi                    

在上例中,如果 myvar 等于 "foo",則代碼將按預想工作,不進(jìn)行打印。但是,如果 myvar 等于 "foo bar oni",則代碼將因以下錯誤失?。?/p>

 [: too many arguments                    

在這種情況下,"$myvar"(等于 "foo bar oni")中的空格迷惑了 bash。bash 擴展 "$myvar" 之后,代碼如下:

 [ foo bar oni = "foo bar oni" ]                    

因為環(huán)境變量沒(méi)放在雙引號中,所以 bash 認為方括號中的自變量過(guò)多??梢杂秒p引號將字符串自變量括起來(lái)消除該問(wèn)題。請記住,如果養成將所有字符串自變量用雙引號括起的習慣,將除去很多類(lèi)似的編程錯誤。"foo bar oni" 比較 應該寫(xiě)成:

 if [ "$myvar" = "foo bar oni" ]                    then                    echo "yes"                    fi                    

更多引用細節

如果要擴展環(huán)境變量,則必須將它們用 雙引號、而不是單引號括起。單引號 禁用 變量(和歷史)擴展。

以上代碼將按預想工作,而不會(huì )有任何令人不快的意外出現。





回頁(yè)首


更多的循環(huán)結構:"while" 和"until"

好了,已經(jīng)講了條件語(yǔ)句,下面該探索 bash 循環(huán)結構了。我們將從標準的 "for" 循環(huán)開(kāi)始。這里有一個(gè)簡(jiǎn)單的例子:

                    #!/usr/bin/env bash                    for x in one two three four                    do                    echo number $x                    done                    輸出:                    number one                    number two                    number three                    number four                    

發(fā)生了什么?"for" 循環(huán)中的 "for x" 部分定義了一個(gè)名為 "$x" 的新環(huán)境變量(也稱(chēng)為循環(huán)控制變量),它的值被依次設置為 "one"、"two"、"three" 和 "four"。每一次賦值之后,執行一次循環(huán)體("do" 和 "done" 之間的代碼)。在循環(huán)體內,象其它環(huán)境變量一樣,使用標準的變量擴展語(yǔ)法來(lái)引用循環(huán)控制變量 "$x"。還要注意,"for" 循環(huán)總是接收 "in" 語(yǔ)句之后的某種類(lèi)型的字列表。在本例中,指定了四個(gè)英語(yǔ)單詞,但是字列表也可以引用磁盤(pán)上的文件,甚至文件通配符??纯聪旅娴睦?,該例演示如何使用標準 shell 通配符:

 #!/usr/bin/env bash                    for myfile in /etc/r*                    do                    if [ -d "$myfile" ]                    then                    echo "$myfile (dir)"                    else                    echo "$myfile"                    fi                    done                    輸出:                    /etc/rc.d (dir)                    /etc/resolv.conf                    /etc/resolv.conf~                    /etc/rpc                    

以上代碼列出在 /etc 中每個(gè)以 "r" 開(kāi)頭的文件。要做到這點(diǎn),bash 在執行循環(huán)之前首先取得通配符 /etc/r*,然后擴展它,用字符串 /etc/rc.d /etc/resolv.conf /etc/resolv.conf~ /etc/rpc 替換。一旦進(jìn)入循環(huán),根據 myfile 是否為目錄,"-d" 條件運算符用來(lái)執行兩個(gè)不同操作。如果是目錄,則將 "(dir)" 附加到輸出行。

還可以在字列表中使用多個(gè)通配符、甚至是環(huán)境變量:

                    for x in /etc/r--? /var/lo* /home/drobbins/mystuff/* /tmp/${MYPATH}/*                    do                    cp $x /mnt/mydir                    done                    

Bash 將在所有正確位置上執行通配符和環(huán)境變量擴展,并可能創(chuàng )建一個(gè)非常長(cháng)的字列表。

雖然所有通配符擴展示例使用了 絕對路徑,但也可以使用相對路徑,如下所示:

                    for x in ../* mystuff/*                    do                    echo $x is a silly file                    done                    

在上例中,bash 相對于當前工作目錄執行通配符擴展,就象在命令行中使用相對路徑一樣。研究一下通配符擴展。您將注意到,如果在通配符中使用絕對路徑,bash 將通配符擴展成一個(gè)絕對路徑列表。否則,bash 將在后面的字列表中使用相對路徑。如果只引用當前工作目錄中的文件(例如,如果輸入 "for x in *"),則產(chǎn)生的文件列表將沒(méi)有路徑信息的前綴。請記住,可以使用 "basename" 可執行程序來(lái)除去前面的路徑信息,如下所示:

                    for x in /var/log/*                    do                    echo `basename $x` is a file living in /var/log                    done                    

當然,在腳本的命令行自變量上執行循環(huán)通常很方便。這里有一個(gè)如何使用本文開(kāi)始提到的 "$@" 變量的例子:

                    #!/usr/bin/env bash                    for thing in "$@"                    do                    echo you typed ${thing}.                    done                    輸出:                    $ allargs hello there you silly                    you typed hello.                    you typed there.                    you typed you.                    you typed silly.                    





回頁(yè)首


Shell 算術(shù)

在學(xué)習另一類(lèi)型的循環(huán)結構之前,最好先熟悉如何執行 shell 算術(shù)。是的,確實(shí)如此:可以使用 shell 結構來(lái)執行簡(jiǎn)單的整數運算。只需將特定的算術(shù)表達式用 "$((" 和 "))" 括起,bash 就可以計算表達式。這里有一些例子:

 $ echo $(( 100 / 3 ))                    33                    $ myvar="56"                    $ echo $(( $myvar + 12 ))                    68                    $ echo $(( $myvar - $myvar ))                    0 $ myvar=$(( $myvar + 1 ))                    $ echo $myvar                    57                    





回頁(yè)首


更多的循環(huán)結構:"while" 和"until"

只要特定條件為真,"while" 語(yǔ)句就會(huì )執行,其格式如下:

 while [ condition ]                    do                    statements                    done                    

通常使用 "While" 語(yǔ)句來(lái)循環(huán)一定次數,比如,下例將循環(huán) 10 次:

 myvar=0                    while [ $myvar -ne 10 ]                    do                    echo $myvar                    myvar=$(( $myvar + 1 ))                    done                    

可以看到,上例使用了算術(shù)表達式來(lái)使條件最終為假,并導致循環(huán)終止。

"Until" 語(yǔ)句提供了與 "while" 語(yǔ)句相反的功能:只要特定條件為 ,它們就重復。下面是一個(gè)與前面的 "while" 循環(huán)具有同等功能的 "until" 循環(huán):

 myvar=0                    until [ $myvar -eq 10 ]                    do                    echo $myvar                    myvar=$(( $myvar + 1 ))                    done                    





回頁(yè)首


Case 語(yǔ)句

Case 語(yǔ)句是另一種便利的條件結構。這里有一個(gè)示例片段:

                    case "${x##*.}" in                    gz)                    gzunpack ${SROOT}/${x}                    ;;                    bz2)                    bz2unpack ${SROOT}/${x}                    ;;                    *)                    echo "Archive format not recognized."                    exit                    ;;                    esac                    

在上例中,bash 首先擴展 "${x##*.}"。在代碼中,"$x" 是文件的名稱(chēng),"${x##.*}" 除去文件中最后句點(diǎn)后文本之外的所有文本。然后,bash 將產(chǎn)生的字符串與 ")" 左邊列出的值做比較。在本例中,"${x##.*}" 先與 "gz" 比較,然后是 "bz2",最后是 "*"。如果 "${x##.*}" 與這些字符串或模式中的任何一個(gè)匹配,則執行緊接 ")" 之后的行,直到 ";;" 為止,然后 bash 繼續執行結束符 "esac" 之后的行。如果不匹配任何模式或字符串,則不執行任何代碼行,在這個(gè)特殊的代碼片段中,至少要執行一個(gè)代碼塊,因為任何不與 "gz" 或 "bz2" 匹配的字符串都將與 "*" 模式匹配。





回頁(yè)首


函數與名稱(chēng)空間

在 bash 中,甚至可以定義與其它過(guò)程語(yǔ)言(如 Pascal 和 C)類(lèi)似的函數。在 bash 中,函數甚至可以使用與腳本接收命令行自變量類(lèi)似的方式來(lái)接收自變量。讓我們看一下樣本函數定義,然后再從那里繼續:

                    tarview() {                    echo -n "Displaying contents of $1 "                    if [ ${1##*.} = tar ]                    then                    echo "(uncompressed tar)"                    tar tvf $1                    elif [ ${1##*.} = gz ]                    then                    echo "(gzip-compressed tar)"                    tar tzvf $1                    elif [ ${1##*.} = bz2 ]                    then                    echo "(bzip2-compressed tar)"                    cat $1 | bzip2 -d | tar tvf -                    fi                    }                    

另一種情況

可以使用 "case" 語(yǔ)句來(lái)編寫(xiě)上面的代碼。您知道如何編寫(xiě)嗎?

我們在上面定義了一個(gè)名為 "tarview" 的函數,它接收一個(gè)自變量,即某種類(lèi)型的 tar 文件。在執行該函數時(shí),它確定自變量是哪種 tar 文件類(lèi)型(未壓縮的、gzip 壓縮的或 bzip2 壓縮的),打印一行信息性消息,然后顯示 tar 文件的內容。應該如下調用上面的函數(在輸入、粘貼或找到該函數后,從腳本或命令行調用它):

 $ tarview shorten.tar.gz                    Displaying contents of shorten.tar.gz (gzip-compressed tar)                    drwxr-xr-x ajr/abbot         0 1999-02-27 16:17 shorten-2.3a/                    -rw-r--r-- ajr/abbot      1143 1997-09-04 04:06 shorten-2.3a/Makefile                    -rw-r--r-- ajr/abbot      1199 1996-02-04 12:24 shorten-2.3a/INSTALL                    -rw-r--r-- ajr/abbot       839 1996-05-29 00:19 shorten-2.3a/LICENSE                    ....                    

交互地使用它們

別忘了,可以將函數(如上面的函數)放在 ~/.bashrc 或 ~/.bash_profile 中,以便在 bash 中隨時(shí)使用它們。

如您所見(jiàn),可以使用與引用命令行自變量同樣的機制來(lái)在函數定義內部引用自變量。另外,將把 "$#" 宏擴展成包含自變量的數目。唯一可能不完全相同的是變量 "$0",它將擴展成字符串 "bash"(如果從 shell 交互運行函數)或調用函數的腳本名稱(chēng)。





回頁(yè)首


名稱(chēng)空間

經(jīng)常需要在函數中創(chuàng )建環(huán)境變量。雖然有可能,但是還有一個(gè)技術(shù)細節應該了解。在大多數編譯語(yǔ)言(如 C)中,當在函數內部創(chuàng )建變量時(shí),變量被放置在單獨的局部名稱(chēng)空間中。因此,如果在 C 中定義一個(gè)名為 myfunction 的函數,并在該函數中定義一個(gè)名為 "x" 的自變量,則任何名為 "x" 的全局變量(函數之外的變量)將不受它的印象,從而消除了負作用。

在 C 中是這樣,但在 bash 中卻不是。在 bash 中,每當在函數內部創(chuàng )建環(huán)境變量,就將其添加到 全局名稱(chēng)空間。這意味著(zhù),該變量將重寫(xiě)函數之外的全局變量,并在函數退出之后繼續存在:

 #!/usr/bin/env bash                    myvar="hello"                    myfunc() {                    myvar="one two three"                    for x in $myvar                    do                    echo $x                    done                    }                    myfunc                    echo $myvar $x                    

運行此腳本時(shí),它將輸出 "one two three three",這顯示了在函數中定義的 "$myvar" 如何影響全局變量 "$myvar",以及循環(huán)控制變量 "$x" 如何在函數退出之后繼續存在(如果 "$x" 全局變量存在,也將受到影響)。

在這個(gè)簡(jiǎn)單的例子中,很容易找到該錯誤,并通過(guò)使用其它變量名來(lái)改正錯誤。但這不是正確的方法,解決此問(wèn)題的最好方法是通過(guò)使用 "local" 命令,在一開(kāi)始就預防影響全局變量的可能性。當使用 "local" 在函數內部創(chuàng )建變量時(shí),將把它們放在 局部名稱(chēng)空間中,并且不會(huì )影響任何全局變量。這里演示了如何實(shí)現上述代碼,以便不重寫(xiě)全局變量:

                    #!/usr/bin/env bash                    myvar="hello"                    myfunc() {                    local x                    local myvar="one two three"                    for x in $myvar                    do                    echo $x                    done                    }                    myfunc                    echo $myvar $x                    

此函數將輸出 "hello" -- 不重寫(xiě)全局變量 "$myvar","$x" 在 myfunc 之外不繼續存在。在函數的第一行,我們創(chuàng )建了以后要使用的局部變量 x,而在第二個(gè)例子 (local myvar="one two three"") 中,我們創(chuàng )建了局部變量 myvar, 同時(shí) 為其賦值。在將循環(huán)控制變量定義為局部變量時(shí),使用第一種形式很方便,因為不允許說(shuō):"for local x in $myvar"。此函數不影響任何全局變量,鼓勵您用這種方式設計所有的函數。只有在明確希望要修改全局變量時(shí),才 應該使用 "local"。





回頁(yè)首


結束語(yǔ)

我們已經(jīng)學(xué)習了最基本的 bash 功能,現在要看一下如何基于 bash 開(kāi)發(fā)整個(gè)應用程序。下一部分正要講到。再見(jiàn)!



參考資料



關(guān)于作者

Daniel Robbins 居住在新墨西哥州的 Albuquerque。他是 Gentoo 項目 的總設計師,Gentoo Technologies, Inc. 的 CEO,Linux Advanced Multimedia Project (LAMP) 的顧問(wèn),Macmillan 書(shū)籍 Caldera OpenLinux Unleashed、 SuSE Linux UnleashedSamba Unleashed 的作者。Daniel 自小學(xué)二年級起就與計算機結下不解之緣,那時(shí)他首先接觸的是 Logo 程序語(yǔ)言,并沉溺于 Pac-Man 游戲中。這也許就是他至今仍擔任 SONY Electronic Publishing/Psygnosis 首席圖形設計師的原因所在。Daniel 喜歡與妻子 Mary 一起共渡時(shí)光,他們的孩子將在今年春天誕生??赏ㄟ^(guò) drobbins@gentoo.org 與 Daniel Robbins 取得聯(lián)系。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Bash編程實(shí)例 一
40 個(gè)簡(jiǎn)單又有效的 Linux Shell 腳本示例
shell復習摘要(三)
精簡(jiǎn)Bash程序設計教程一:變量的使用 - yunshichen - IT博客
awk正則表達式中調用ksh變量
Shell中的循環(huán)語(yǔ)句for、while、until實(shí)例講解
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久