<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                從這一章開始,我們將建設一個項目。這個項目的目的是為了了解怎樣使用各種各樣的 shell 功能來 創建程序,更重要的是,創建好程序。 我們將要編寫的程序是一個報告生成器。它會顯示系統的各種統計數據和它的狀態,并將產生 HTML 格式的報告, 所以我們能通過網絡瀏覽器,比如說 Firefox 或者 Konqueror,來查看這個報告。 通常,創建程序要經過一系列階段,每個階段會添加新的特性和功能。我們程序的第一個階段將會 產生一個非常小的 HTML 網頁,其不包含系統信息。隨后我們會添加這些信息。 ## 第一階段:最小的文檔 首先我們需要知道的事是一個規則的 HTML 文檔的格式。它看起來像這樣: ~~~ <HTML> <HEAD> <TITLE>Page Title</TITLE> </HEAD> <BODY> Page body. </BODY> </HTML> ~~~ 如果我們將這些內容輸入到文本編輯器中,并把文件保存為 foo.html,然后我們就能在 Firefox 中 使用下面的 URL 來查看文件內容: ~~~ file:///home/username/foo.html ~~~ 程序的第一個階段將這個 HTML 文件輸出到標準輸出。我們可以編寫一個程序,相當容易地完成這個任務。 啟動我們的文本編輯器,然后創建一個名為 ~/bin/sys_info_page 的新文件: ~~~ [me@linuxbox ~]$ vim ~/bin/sys_info_page ~~~ 隨后輸入下面的程序: ~~~ #!/bin/bash # Program to output a system information page echo "<HTML>" echo " <HEAD>" echo " <TITLE>Page Title</TITLE>" echo " </HEAD>" echo " <BODY>" echo " Page body." echo " </BODY>" echo "</HTML>" ~~~ 我們第一次嘗試解決這個問題,程序包含了一個 shebang,一條注釋(總是一個好主意)和一系列的 echo 命令,每個命令負責輸出一行文本。保存文件之后,我們將讓它成為可執行文件,再嘗試運行它: ~~~ [me@linuxbox ~]$ chmod 755 ~/bin/sys_info_page [me@linuxbox ~]$ sys_info_page ~~~ 當程序運行的時候,我們應該看到 HTML 文本在屏幕上顯示出來,因為腳本中的 echo 命令會輸出 發送到標準輸出。我們再次運行這個程序,把程序的輸出重定向到文件 sys_info_page.html 中, 從而我們可以通過網絡瀏覽器來查看輸出結果: ~~~ [me@linuxbox ~]$ sys_info_page > sys_info_page.html [me@linuxbox ~]$ firefox sys_info_page.html ~~~ 到目前為止,一切順利。 在編寫程序的時候,盡量做到簡單明了,這總是一個好主意。當一個程序易于閱讀和理解的時候, 維護它也就更容易,更不用說,通過減少鍵入量,可以使程序更容易書寫了。我們當前的程序版本 工作正常,但是它可以更簡單些。實際上,我們可以把所有的 echo 命令結合成一個 echo 命令,當然 這樣能更容易地添加更多的文本行到程序的輸出中。那么,把我們的程序修改為: ~~~ #!/bin/bash # Program to output a system information page echo "<HTML> <HEAD> <TITLE>Page Title</TITLE> </HEAD> <BODY> Page body. </BODY> </HTML>" ~~~ 一個帶引號的字符串可能包含換行符,因此可以包含多個文本行。Shell 會持續讀取文本直到它遇到 右引號。它在命令行中也是這樣工作的: ~~~ [me@linuxbox ~]$ echo "<HTML> > <HEAD> <TITLE>Page Title</TITLE> > </HEAD> > <BODY> > Page body. > </BODY> ></HTML>" ~~~ 開頭的 “>” 字符是包含在 PS2shell 變量中的 shell 提示符。每當我們在 shell 中鍵入多行語句的時候, 這個提示符就會出現。現在這個功能有點兒晦澀,但隨后,當我們介紹多行編程語句時,它會派上大用場。 ## 第二階段:添加一點兒數據 現在我們的程序能生成一個最小的文檔,讓我們給報告添加些數據吧。為此,我們將做 以下修改: ~~~ #!/bin/bash # Program to output a system information page echo "<HTML> <HEAD> <TITLE>System Information Report</TITLE> </HEAD> <BODY> <H1>System Information Report</H1> </BODY> </HTML>" ~~~ 我們增加了一個網頁標題,并且在報告正文部分加了一個標題。 ## 變量和常量 然而,我們的腳本存在一個問題。請注意字符串 “System Information Report” 是怎樣被重復使用的?對于這個微小的腳本而言,它不是一個問題,但是讓我們設想一下, 我們的腳本非常冗長,并且我們有許多這個字符串的實例。如果我們想要更換一個標題,我們必須 對腳本中的許多地方做修改,這會是很大的工作量。如果我們能整理一下腳本,讓這個字符串只 出現一次而不是多次,會怎樣呢?這樣會使今后的腳本維護工作更加輕松。我們可以這樣做: ~~~ #!/bin/bash # Program to output a system information page title="System Information Report" echo "<HTML> <HEAD> <TITLE>$title</TITLE> </HEAD> <BODY> <H1>$title</H1> </BODY> </HTML>" ~~~ 通過創建一個名為 title 的變量,并把 “System Information Report” 字符串賦值給它,我們就可以利用參數展開功能,把這個字符串放到文件中的多個位置。 那么,我們怎樣來創建一個變量呢?很簡單,我們只管使用它。當 shell 碰到一個變量的時候,它會 自動地創建它。這不同于許多編程語言,它們中的變量在使用之前,必須顯式的聲明或是定義。關于 這個問題,shell 要求非常寬松,這可能會導致一些問題。例如,考慮一下在命令行中發生的這種情形: ~~~ [me@linuxbox ~]$ foo="yes" [me@linuxbox ~]$ echo $foo yes [me@linuxbox ~]$ echo $fool [me@linuxbox ~]$ ~~~ 首先我們把 “yes” 賦給變量 foo,然后用 echo 命令來顯示變量值。接下來,我們顯示拼寫錯誤的變量名 “fool” 的變量值,然后得到一個空值。這是因為 shell 很高興地創建了變量 fool,當 shell 遇到 fool 的時候, 并且賦給 fool 一個空的默認值。因此,我們必須小心謹慎地拼寫!同樣理解實例中究竟發生了什么事情也 很重要。從我們以前學習 shell 執行展開操作,我們知道這個命令: ~~~ [me@linuxbox ~]$ echo $foo ~~~ 經歷了參數展開操作,然后得到: ~~~ [me@linuxbox ~]$ echo yes ~~~ 然而這個命令: ~~~ [me@linuxbox ~]$ echo $fool ~~~ 展開為: ~~~ [me@linuxbox ~]$ echo ~~~ 這個空變量展開值為空!對于需要參數的命令來說,這會引起混亂。下面是一個例子: ~~~ [me@linuxbox ~]$ foo=foo.txt [me@linuxbox ~]$ foo1=foo1.txt [me@linuxbox ~]$ cp $foo $fool cp: missing destination file operand after `foo.txt' Try `cp --help' for more information. ~~~ 我們給兩個變量賦值,foo 和 foo1。然后我們執行 cp 操作,但是拼寫錯了第二個參數的名字。 參數展開之后,這個 cp 命令只接受到一個參數,雖然它需要兩個。 有一些關于變量名的規則: 1. 變量名可由字母數字字符(字母和數字)和下劃線字符組成。 2. 變量名的第一個字符必須是一個字母或一個下劃線。 3. 變量名中不允許出現空格和標點符號。 單詞 “variable” 意味著可變的值,并且在許多應用程序當中,都是以這種方式來使用變量的。然而, 我們應用程序中的變量,title,被用作一個常量。常量有一個名字且包含一個值,在這方面就 像是變量。不同之處是常量的值是不能改變的。在執行幾何運算的應用程序中,我們可以把 PI 定義為 一個常量,并把 3.1415 賦值給它,用它來代替數字字面值。shell 不能辨別變量和常量;它們大多數情況下 是為了方便程序員。一個常用慣例是指定大寫字母來表示常量,小寫字母表示真正的變量。我們 將修改我們的腳本來遵從這個慣例: ~~~ #!/bin/bash # Program to output a system information page TITLE="System Information Report For $HOSTNAME" echo "<HTML> <HEAD> <TITLE>$title</TITLE> </HEAD> <BODY> <H1>$title</H1> </BODY> </HTML>" ~~~ 我們亦借此機會,通過在標題中添加 shell 變量名 HOSTNAME,讓標題變得活潑有趣些。 這個變量名是這臺機器的網絡名稱。 * * * 注意:實際上,shell 確實提供了一種方法,通過使用帶有-r(只讀)選項的內部命令 declare, 來強制常量的不變性。如果我們給 TITLE 這樣賦值: 那么 shell 會阻止之后給 TITLE 的任意賦值。這個功能極少被使用,但為了很早之前的腳本, 它仍然存在。 * * * ### 給變量和常量賦值 這里是我們真正開始使用參數擴展知識的地方。正如我們所知道的,這樣給變量賦值: ~~~ variable=value ~~~ 這里的variable是變量的名字,value是一個字符串。不同于一些其它的編程語言,shell 不會 在乎變量值的類型;它把它們都看作是字符串。通過使用帶有-i 選項的 declare 命令,你可以強制 shell 把 賦值限制為整型,但是,正如像設置變量為只讀一樣,極少這樣做。 注意在賦值過程中,變量名,等號和變量值之間必須沒有空格。那么,這些值由什么組成呢? 可以展開成字符串的任意值: ~~~ a=z # Assign the string "z" to variable a. b="a string" # Embedded spaces must be within quotes. c="a string and $b" # Other expansions such as variables can be # expanded into the assignment. d=$(ls -l foo.txt) # Results of a command. e=$((5 * 7)) # Arithmetic expansion. f="\t\ta string\n" # Escape sequences such as tabs and newlines. ~~~ 可以在同一行中對多個變量賦值: ~~~ a=5 b="a string" ~~~ 在參數展開過程中,變量名可能被花括號 “{}” 包圍著。由于變量名周圍的上下文,其變得不明確的情況下, 這會很有幫助。這里,我們試圖把一個文件名從 myfile 改為 myfile1,使用一個變量: ~~~ [me@linuxbox ~]$ filename="myfile" [me@linuxbox ~]$ touch $filename [me@linuxbox ~]$ mv $filename $filename1 mv: missing destination file operand after `myfile' Try `mv --help' for more information. ~~~ 這種嘗試失敗了,因為 shell 把 mv 命令的第二個參數解釋為一個新的(并且空的)變量。通過這種方法 可以解決這個問題: ~~~ [me@linuxbox ~]$ mv $filename ${filename}1 ~~~ 通過添加花括號,shell 不再把末尾的1解釋為變量名的一部分。 我們將利用這個機會來添加一些數據到我們的報告中,即創建包括的日期和時間,以及創建者的用戶名: ~~~ #!/bin/bash # Program to output a system information page TITLE="System Information Report For $HOSTNAME" CURRENT_TIME=$(date +"%x %r %Z") TIME_STAMP="Generated $CURRENT_TIME, by $USER" echo "<HTML> <HEAD> <TITLE>$TITLE</TITLE> </HEAD> <BODY> <H1>$TITLE</H1> <P>$TIME_STAMP</P> </BODY> </HTML>" ~~~ ## Here Documents 我們已經知道了兩種不同的文本輸出方法,兩種方法都使用了 echo 命令。還有第三種方法,叫做 here document 或者 here script。一個 here document 是另外一種 I/O 重定向形式,我們 在腳本文件中嵌入正文文本,然后把它發送給一個命令的標準輸入。它這樣工作: ~~~ command << token text token ~~~ 這里的 command 是一個可以接受標準輸入的命令名,token 是一個用來指示嵌入文本結束的字符串。 我們將修改我們的腳本,來使用一個 here document: ~~~ #!/bin/bash # Program to output a system information page TITLE="System Information Report For $HOSTNAME" CURRENT_TIME=$(date +"%x %r %Z") TIME_STAMP="Generated $CURRENT_TIME, by $USER" cat << _EOF_ <HTML> <HEAD> <TITLE>$TITLE</TITLE> </HEAD> <BODY> <H1>$TITLE</H1> <P>$TIME_STAMP</P> </BODY> </HTML> _EOF_ ~~~ 取代 echo 命令,現在我們的腳本使用 cat 命令和一個 here document。這個字符串_EOF_(意思是“文件結尾”, 一個常見用法)被選作為 token,并標志著嵌入文本的結尾。注意這個 token 必須在一行中單獨出現,并且文本行中 沒有末尾的空格。 那么使用一個 here document 的優點是什么呢?它很大程度上和 echo 一樣,除了默認情況下,here documents 中的單引號和雙引號會失去它們在 shell 中的特殊含義。這里有一個命令中的例子: ~~~ [me@linuxbox ~]$ foo="some text" [me@linuxbox ~]$ cat << _EOF_ > $foo > "$foo" > '$foo' > \$foo > _EOF_ some text "some text" 'some text' $foo ~~~ 正如我們所見到的,shell 根本沒有注意到引號。它把它們看作是普通的字符。這就允許我們 在一個 here document 中可以隨意的嵌入引號。對于我們的報告程序來說,這將是非常方便的。 Here documents 可以和任意能接受標準輸入的命令一塊使用。在這個例子中,我們使用了 一個 here document 將一系列的命令傳遞到這個 ftp 程序中,為的是從一個遠端 FTP 服務器中得到一個文件: ~~~ #!/bin/bash # Script to retrieve a file via FTP FTP_SERVER=ftp.nl.debian.org FTP_PATH=/debian/dists/lenny/main/installer-i386/current/images/cdrom REMOTE_FILE=debian-cd_info.tar.gz ftp -n << _EOF_ open $FTP_SERVER user anonymous me@linuxbox cd $FTP_PATH hash get $REMOTE_FILE bye _EOF_ ls -l $REMOTE_FILE ~~~ 如果我們把重定向操作符從 “<<” 改為 “<<-”,shell 會忽略在此 here document 中開頭的 tab 字符。 這就能縮進一個 here document,從而提高腳本的可讀性: ~~~ #!/bin/bash # Script to retrieve a file via FTP FTP_SERVER=ftp.nl.debian.org FTP_PATH=/debian/dists/lenny/main/installer-i386/current/images/cdrom REMOTE_FILE=debian-cd_info.tar.gz ftp -n <<- _EOF_ open $FTP_SERVER user anonymous me@linuxbox cd $FTP_PATH hash get $REMOTE_FILE bye _EOF_ ls -l $REMOTE_FILE ~~~ ## 總結歸納 在這一章中,我們啟動了一個項目,其帶領我們領略了創建一個成功腳本的整個過程。 同時我們介紹了變量和常量的概念,以及怎樣使用它們。它們是我們將找到的眾多參數展開應用程序中的第一批實例。 我們也知道了怎樣從我們的腳本文件中產生輸出,及其各種各樣嵌入文本塊的方法。 ## 拓展閱讀 * 關于 HTML 的更多信息,查看下面的文章和教材: [http://en.wikipedia.org/wiki/Html](http://en.wikipedia.org/wiki/Html) [http://en.wikibooks.org/wiki/HTML_Programming](http://en.wikibooks.org/wiki/HTML_Programming) [http://html.net/tutorials/html/](http://html.net/tutorials/html/) * Bash 手冊包括一節“HERE DOCUMENTS”的內容,其詳細的講述了這個功能。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看