<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 12.2 簡單的 shell script 練習 在第一支 shell script 撰寫完畢之后,相信你應該具有基本的撰寫功力了。接下來,在開始更深入的程序概念之前,我們先來玩一些簡單的小范例好了。 下面的范例中,達成結果的方式相當的多,建議你先自行撰寫看看,寫完之后再與鳥哥寫的內容比對, 這樣才能更加深概念喔!好!不啰唆,我們就一個一個來玩吧! ### 12.2.1 簡單范例 下面的范例在很多的腳本程序中都會用到,而下面的范例又都很簡單!值得參考看看喔! * 對談式腳本:變量內容由使用者決定 很多時候我們需要使用者輸入一些內容,好讓程序可以順利運行。 簡單的來說,大家應該都有安裝過軟件的經驗,安裝的時候,他不是會問你“要安裝到那個目錄去”嗎? 那個讓使用者輸入數據的動作,就是讓使用者輸入變量內容啦。 你應該還記得在[十章 bash](../Text/index.html) 的時候,我們有學到一個 [read](../Text/index.html#read) 指令吧?現在,請你以 read 指令的用途,撰寫一個 script ,他可以讓使用者輸入:1\. first name 與 2\. last name, 最后并且在屏幕上顯示:“Your full name is: ”的內容: ``` [dmtsai@study bin]$ vim showname.sh #!/bin/bash # Program: # User inputs his first name and last name. Program shows his full name. # History: # 2015/07/16 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH read -p "Please input your first name: " firstname # 提示使用者輸入 read -p "Please input your last name: " lastname # 提示使用者輸入 echo -e "\nYour full name is: ${firstname} ${lastname}" # 結果由屏幕輸出 ``` 將上面這個 showname.sh 執行一下,你就能夠發現使用者自己輸入的變量可以讓程序所取用,并且將他顯示到屏幕上! 接下來,如果想要制作一個每次執行都會依據不同的日期而變化結果的腳本呢? * 隨日期變化:利用 date 進行文件的創建 想像一個狀況,假設我的服務器內有數據庫,數據庫每天的數據都不太一樣,因此當我備份時,希望將每天的數據都備份成不同的文件名, 這樣才能夠讓舊的數據也能夠保存下來不被覆蓋。哇!不同文件名呢!這真困擾啊?難道要我每天去修改 script ? 不需要啊!考慮每天的“日期”并不相同,所以我可以將文件名取成類似: backup.2015-07-16.data , 不就可以每天一個不同文件名了嗎?呵呵!確實如此。那個 2015-07-16 怎么來的?那就是重點啦!接下來出個相關的例子: 假設我想要創建三個空的文件 (通過 [touch](../Text/index.html#touch)) ,文件名最開頭由使用者輸入決定,假設使用者輸入 filename 好了,那今天的日期是 2015/07/16 , 我想要以前天、昨天、今天的日期來創建這些文件,亦即 filename_20150714, filename_20150715, filename_20150716 ,該如何是好? ``` [dmtsai@study bin]$ vim create_3_filename.sh #!/bin/bash # Program: # Program creates three files, which named by user's input and date command. # History: # 2015/07/16 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH # 1\. 讓使用者輸入文件名稱,并取得 fileuser 這個變量; echo -e "I will use 'touch' command to create 3 files." # 純粹顯示信息 read -p "Please input your filename: " fileuser # 提示使用者輸入 # 2\. 為了避免使用者隨意按 Enter ,利用[變量功能](../Text/index.html#variable_other_re)分析文件名是否有設置? filename=${fileuser:-"filename"} # 開始判斷有否配置文件名 # 3\. 開始利用 date 指令來取得所需要的文件名了; date1=$(date --date='2 days ago' +%Y%m%d) # 前兩天的日期 date2=$(date --date='1 days ago' +%Y%m%d) # 前一天的日期 date3=$(date +%Y%m%d) # 今天的日期 file1=${filename}${date1} # 下面三行在配置文件名 file2=${filename}${date2} file3=${filename}${date3} # 4\. 將文件名創建吧! touch "${file1}" # 下面三行在創建文件 touch "${file2}" touch "${file3}" ``` 上面的范例鳥哥使用了很多在[第十章](../Text/index.html)介紹過的概念: 包括小指令“ $(command) ”的取得訊息、變量的設置功能、變量的累加以及利用 touch 指令輔助! 如果你開始執行這個 create_3_filename.sh 之后,你可以進行兩次執行:一次直接按 [Enter] 來查閱文件名是啥? 一次可以輸入一些字符,這樣可以判斷你的腳本是否設計正確喔! * 數值運算:簡單的加減乘除 各位看官應該還記得,我們可以使用 [declare](../Text/index.html#declare) 來定義變量的類型吧? 當變量定義成為整數后才能夠進行加減運算啊!此外,我們也可以利用“ $((計算式)) ”來進行數值運算的。 可惜的是, bash shell 里頭默認僅支持到整數的數據而已。OK!那我們來玩玩看,如果我們要使用者輸入兩個變量, 然后將兩個變量的內容相乘,最后輸出相乘的結果,那可以怎么做? ``` [dmtsai@study bin]$ vim multiplying.sh #!/bin/bash # Program: # User inputs 2 integer numbers; program will cross these two numbers. # History: # 2015/07/16 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH echo -e "You SHOULD input 2 numbers, I will multiplying them! \n" read -p "first number: " firstnu read -p "second number: " secnu total=$((${firstnu}*${secnu})) echo -e "\nThe result of ${firstnu} x ${secnu} is ==&gt; ${total}" ``` 在數值的運算上,我們可以使用“ declare -i total=${firstnu}*${secnu} ” 也可以使用上面的方式來進行!基本上,鳥哥比較建議使用這樣的方式來進行運算: > var=$((運算內容)) 不但容易記憶,而且也比較方便的多,因為兩個小括號內可以加上空白字符喔! 未來你可以使用這種方式來計算的呀!至于數值運算上的處理,則有:“ +, -, *, /, % ”等等。 那個 % 是取余數啦~舉例來說, 13 對 3 取余數,結果是 13=4*3+1,所以余數是 1 啊!就是: ``` [dmtsai@study bin]$ echo $(( 13 % 3 )) 1 ``` 這樣了解了吧?另外,如果你想要計算含有小數點的數據時,其實可以通過 [bc](../Text/index.html#bc) 這個指令的協助喔! 例如可以這樣做: ``` [dmtsai@study bin]$ echo "123.123*55.9" &#124; bc 6882.575 ``` 了解了 bc 的妙用之后,來讓我們測試一下如何計算 pi 這個東西呢? * 數值運算:通過 bc 計算 pi 其實計算 pi 時,小數點以下位數可以無限制的延伸下去!而 bc 有提供一個運算 pi 的函數,只是想要使用該函數必須要使用 bc -l 來調用才行。 也因為這個小數點以下位數可以無線延伸運算的特性存在,所以我們可以通過下面這只小腳本來讓使用者輸入一個“小數點為數值”, 以讓 pi 能夠更準確! ``` [dmtsai@study bin]$ vim cal_pi.sh #!/bin/bash # Program: # User input a scale number to calculate pi number. # History: # 2015/07/16 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH echo -e "This program will calculate pi value. \n" echo -e "You should input a float number to calculate pi value.\n" read -p "The scale number (10~10000) ? " checking num=${checking:-"10"} # 開始判斷有否有輸入數值 echo -e "Starting calcuate pi value. Be patient." time echo "scale=${num}; 4*a(1)" &#124; bc -lq ``` 上述數據中,那個 4*a(1) 是 bc 主動提供的一個計算 pi 的函數,至于 scale 就是要 bc 計算幾個小數點下位數的意思。當 scale 的數值越大, 代表 pi 要被計算的越精確,當然用掉的時間就會越多!因此,你可以嘗試輸入不同的數值看看!不過,最好是不要超過 5000 啦!因為會算很久! 如果你要讓你的 CPU 隨時保持在高負載,這個程序算下去你就會知道有多操 CPU 啰! ^_^ ![鳥哥的圖示](https://box.kancloud.cn/2016-05-13_5735736501917.gif "鳥哥的圖示") **Tips** 鳥哥的實驗室中,為了要確認虛擬機的效率問題,所以很多時候需要保持虛擬機在忙碌的狀態~鳥哥的學生就是丟這只程序進去系統跑! 但是將 scale 調高一些,那計算就得要花比較多時間~用以達到我們需要 CPU 忙碌的狀態喔! ### 12.2.2 script 的執行方式差異 (source, sh script, ./script) 不同的 script 執行方式會造成不一樣的結果喔!尤其影響 bash 的環境很大呢!腳本的執行方式除了[前面小節談到的方式](../Text/index.html#script_run)之外,還可以利用 [source](../Text/index.html#source) 或小數點 (.) 來執行喔!那么這種執行方式有何不同呢?當然是不同的啦!讓我們來說說! * 利用直接執行的方式來執行 script 當使用前一小節提到的直接指令下達 (不論是絕對路徑/相對路徑還是 ${PATH} 內),或者是利用 bash (或 sh) 來下達腳本時, 該 script 都會使用一個新的 bash 環境來執行腳本內的指令!也就是說,使用這種執行方式時, 其實 script 是在子程序的 bash 內執行的!我們在[第十章 BASH](../Text/index.html) 內談到 [export](../Text/index.html#export) 的功能時,曾經就父程序/子程序談過一些概念性的問題, 重點在于:“當子程序完成后,在子程序內的各項變量或動作將會結束而不會傳回到父程序中”! 這是什么意思呢? 我們舉剛剛提到過的 showname.sh 這個腳本來說明好了,這個腳本可以讓使用者自行設置兩個變量,分別是 firstname 與 lastname,想一想,如果你直接執行該指令時,該指令幫你設置的 firstname 會不會生效?看一下下面的執行結果: ``` [dmtsai@study bin]$ echo ${firstname} ${lastname} &lt;==確認了,這兩個變量并不存在喔! [dmtsai@study bin]$ sh showname.sh Please input your first name: VBird &lt;==這個名字是鳥哥自己輸入的 Please input your last name: Tsai Your full name is: VBird Tsai &lt;==看吧!在 script 運行中,這兩個變量有生效 [dmtsai@study bin]$ echo ${firstname} ${lastname} &lt;==事實上,這兩個變量在父程序的 bash 中還是不存在的! ``` 上面的結果你應該會覺得很奇怪,怎么我已經利用 showname.sh 設置好的變量竟然在 bash 環境下面無效!怎么回事呢? 如果將程序相關性繪制成圖的話,我們以下圖來說明。當你使用直接執行的方法來處理時,系統會給予一支新的 bash 讓我們來執行 showname.sh 里面的指令,因此你的 firstname, lastname 等變量其實是在下圖中的子程序 bash 內執行的。 當 showname.sh 執行完畢后,子程序 bash 內的所有數據便被移除,因此上表的練習中,在父程序下面 echo ${firstname} 時, 就看不到任何東西了!這樣可以理解嗎? ![showname.sh 在子程序當中運行的示意圖](https://box.kancloud.cn/2016-05-13_573573781f158.gif)圖12.2.1、showname.sh 在子程序當中運行的示意圖 * 利用 source 來執行腳本:在父程序中執行 如果你使用 source 來執行指令那就不一樣了!同樣的腳本我們來執行看看: ``` [dmtsai@study bin]$ source showname.sh Please input your first name: VBird Please input your last name: Tsai Your full name is: VBird Tsai [dmtsai@study bin]$ echo ${firstname} ${lastname} VBird Tsai &lt;==嘿嘿!有數據產生喔! ``` 竟然生效了!沒錯啊!因為 source 對 script 的執行方式可以使用下面的圖示來說明! showname.sh 會在父程序中執行的,因此各項動作都會在原本的 bash 內生效!這也是為啥你不登出系統而要讓某些寫入 ~/.bashrc 的設置生效時,需要使用“ source ~/.bashrc ”而不能使用“ bash ~/.bashrc ”是一樣的啊! ![showname.sh 在父程序當中運行的示意圖](https://box.kancloud.cn/2016-05-13_5735737830f7b.gif)圖12.2.2、showname.sh 在父程序當中運行的示意圖
                  <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>

                              哎呀哎呀视频在线观看