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

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 第七章:shell相關 ## 區分登錄/非登錄shell,以及交互式/非交互式shell ### 登錄/非登錄shell - 登錄shell(login shell)指的是需要用戶輸入用戶名和密碼才能進去的shell,這是比較常用的。 - 非登錄shell(non-login shell)則相反,不需要用戶輸入用戶名和密碼,例如: - 直接命令`bash`(不帶`--login`參數)就是打開一個新的非登錄shell。 - 在圖形界面(如Gnome或KDE)中打開一個“終端”(terminal)窗口程序也是屬于打開了一個非登錄shell。 ### 交互式/非交互式shell - 交互式shell(interactive shell)指的是shell等待自然人用戶在終端上的輸入,并且按照用戶輸入的命令立即執行且返回執行結果,這種操作模式被稱為“交互式模式”,是我們最直觀、最常用的操作方式。 - 非交互式shell(non-interactive shell)針對的并非自然人用戶,它通常是以 shell script (即以 shell 的語法所寫成的程序代碼段)的方式執行。 - 運行shell腳本程序時,系統將創建一個子shell。此時,系統中將有兩個shell,一個是登錄時系統啟動的shell,另一個是系統為運行腳本程序創建的shell。 - 當一個腳本程序運行完畢,它的腳本shell將終止,可以返回到執行該腳本之前的shell。 - 從這種意義上來說,用戶可以有許多 shell,每個shell都是由某個shell(稱為父shell)派生的。 ### 不同類型shell初始化時所執行的startup腳本不一樣 > 對于Bash來說,登錄shell(包括交互式登錄shell和使用`–-login`選項的非交互shell),它會首先讀取和執行`/etc/profile`全局配置文件中的命令,然后依次查找`~/.bash_profile`、`~/.bash_login` 和 `~/.profile`這三個配置文件,讀取和執行這三個中的第一個存在且可讀的文件中命令。除非被`–noprofile`選項禁止了。另外,由于`~/.bash_profile`一般也會帶有執行`~/.bashrc`的代碼段,因此`~/.bashrc`的內容也會被執行。 > 在非登錄shell里,只讀取 `~/.bashrc` (和 `/etc/bash.bashrc`、`/etc/bashrc` )文件,不同的發行版里面可能有所不同。 從上可得,無論是登錄shell還是非登錄shell,最終都會執行`~/.bashrc`。 ## 如何讓變量突破shell腳本程序的上下文限制:`export`與`source` 在子 shell 中定義的變量只在該子 shell 內有效。如果在一個 shell 腳本程序中定義了一個變量,當該腳本程序運行時,這個定義的變量只是該腳本程序內的一個局部變量,其他的 shell 不能引用它。 有兩種方法可以使子 shell 中的變量突破上下文限制,在其它 shell 中也能使用: - 在腳本代碼中使用`export`語句可以對已定義的變量進行輸出,如下: ``` a=2333 export a ``` `export`命令將使系統在創建每一個新的子 shell 時定義這個變量的一個拷貝。這個過程稱之為變量輸出。 - 在交互式 shell 中使用`source`命令來執行腳本程序,系統將不會生成新的子 shell 來執行腳本程序,而是直接在當前的交互式 shell 中執行;那么,腳本程序中所有定義(或改變)的變量,都將在當前 shell 中起效。 ## 如何配置Linux用戶的工作環境,并在下次登錄依然保持有效 當我們直接在命令行里執行配置工作環境的命令,如`alias`,賦值自定義變量等操作時,這些配置僅適用于當前登錄的會話,若當前用戶退出系統,則這些配置均失效。 首先需要明確的是,既然針對的是“Linux用戶的工作環境”,那么實際上我們執行的是**登錄交互式shell**;因此,若想要這些工作環境的配置在下次登錄依然保持有效,可以這樣做: - “全局配置”,指的是為當前系統的每一個用戶都設置一致的工作環境配置。全局配置的方式是:在`/etc/profile`文件中進行編輯或添加命令語句。 - “每個用戶私有配置”,指的是針對Linux中具體某個用戶進行特定的工作環境配置,其方式為:在`~/.bash_profile`中進行編輯或添加命令語句。 ## shell變量規則 - 賦值變量的格式為`a=b`,其中a為變量名,b為賦給變量的值,需要注意的是,等號兩邊不能有空格。 - 變量名只能由字母、數字以及下劃線組成,而且不能以數字開頭。 - 當變量內容帶有特殊字符(如空格)時,需要加上單引號,如`myname='array huang'`;如果變量內容中本來就含有單引號,此時就需要加雙引號了,如`myname="'array huang'"`。 - 如變量中需要用到linux命令的執行結果,可以使用反引號,如 ``` pwdResult=`pwd` ``` - 拼接變量的方法如下:`myname="$firstName"Huang` ## `grep`命令和`egrep`命令不一樣的地方 `egrep`是`grep`的擴展版本,因此在功能上前者比后者更為強大,下面介紹它們不同的地方: - `egrep`支持更多的正則表達式用法: - `?`(表示0個或1個指定的字符); - `+`(表示至少1個指定的字符); - `|`(邏輯或連接符),如`'a|b'`,指的是匹配含有 a **或** b 的字符串; - `()`表示把多個字符合為1個整體來進行表達,通常搭配其它正則表達式符號來使用,如`'r(oo|at)o'`,指的是匹配含有 rooo 或 rato 的字符串; - 在`{}`的用法上,`grep`的使用比較麻煩,需要加上轉義字符`\`,如`'o\{2\}'`(表示匹配含有 oo 的字符串);而`egrep`的使用則自然得多,同樣的正則表達式,直接使用`'o{2}'`即可。 ## shell腳本 ### shell腳本的創建和執行 - shell腳本應以`#! /bin/bash`開頭來表明該腳本使用的是 bash 語法,如果不寫,也能正常運行,但就不符合編碼規范了。 - shell腳本的執行有兩種方法: - 執行命令`sh ./file.sh`,并且可以考慮加上`-x`參數,這樣就能查看腳本每一步執行的命令與結果了,非常利于調試程序。 - 直接執行`./file.sh`,這種方法使用的前提是用戶擁有腳本的執行權限(即**x**權限),需要注意的是新建腳本文件時一般是沒有執行權限的,需要通過`chmod`進行修改。 因此一般我們直接用第一種方法即可。 ### 腳本常用命令及語法 在 shell 腳本中,命令可看作是一般程序語言中的預設函數。 #### 時間 `date`,時間格式化和簡單的計算(如“一天前”、“一小時后”等)。 - 命令(函數)的結果可以通過反引號來賦值給變量,如 ``` nowDate=`date +"%Y-%m-%d"` ``` #### 數學運算 - 數學運算有特別的語法: - 用`$[]`給括起來(只支持整數運算),如: ``` a=1 b=2 c=$[$a+$b+3] echo $c // 結果是6 ``` - - 使用`let`(只支持整數運算): ``` var=1 let "var+=1" echo $var ``` - - 使用`(())`(只支持整數運算): ``` var=1 ((var+=1)) echo $var ``` - - 使用bc(可以進行浮點數計算): ``` var=1 var=`echo "$var+1"|bc` echo $var ``` 其原理是:bc是linux下的一個簡單計算器,支持浮點數計算,在命令行下輸入bc即進入計算器程序,而我們想在程序中直接進行浮點數計算時,利用一個簡單的管道即可解決問題。 #### 和用戶交互 使用`read`命令可達到與用戶交互的目的,它會把用戶輸入的字符串作為變量值,如: ``` read -p "please input a number:" x # 執行后等待用戶輸入并按回車確認 echo "$x" ``` #### 執行shell腳本時傳參 在執行腳本時,我們可以通過對腳本傳參(當然前提是腳本被設計成可以接受參數),來改變腳本的具體行為,以及得到以此計算出來的結果。 腳本內獲取參數的格式為:$n。(n代表一個數字,,1 為執行腳本的第一個參數,2 為執行腳本的第二個參數,以此類推……)。 舉例說明,當前有一個名為**test.sh**的腳本: ``` #!/bin/bash echo "Shell 輸出腳本名稱及參數"; echo "執行的腳本名:$0"; echo "第一個參數為:$1"; echo "第二個參數為:$2"; echo "第三個參數為:$3"; ``` 運行輸出: ``` $ ./test.sh 1 2 3 Shell 傳遞參數實例! 執行的文件名:./test.sh 第一個參數為:1 第二個參數為:2 第三個參數為:3 ``` #### 邏輯判斷 共有以下3種語法: - 不帶`else`: ``` if [判斷語句]; then command fi ``` - 帶`else`: ``` if [判斷語句]; then command else command fi ``` - 帶`elif`: ``` if [判斷語句]; then command elif [判斷語句]; then command else command fi ``` ##### if語句 ###### 字符串判斷 - str1 = str2      當兩個串有相同內容、長度時為真 - str1 != str2      當串str1和str2不等時為真 - -n str1        當串的長度大于0時為真(串非空) - -z str1        當串的長度為0時為真(空串) - str1         當串str1為非空時為真 ###### 數字的判斷 - int1 -eq int2    兩數相等為真 - int1 -ne int2    兩數不等為真 - int1 -gt int2    int1大于int2為真 - int1 -ge int2    int1大于等于int2為真 - int1 -lt int2    int1小于int2為真 - int1 -le int2    int1小于等于int2為真 ###### 文件的判斷 - -r file     用戶可讀為真 - -w file     用戶可寫為真 - -x file     用戶可執行為真 - -f file     文件為正規文件為真 - -d file     文件為目錄為真 - -c file     文件為字符特殊文件為真 - -b file     文件為塊特殊文件為真 - -s file     文件大小非0時為真 - -t file     當文件描述符(默認為1)指定的設備為終端時為真 ###### 復雜邏輯判斷 - &&         與 - ||        或 - !        非 舉例: ``` a=10 if [$a -lt 1] || [$a -gt 5]; then echo ok; # 輸出ok fi ``` #### case語句 語法如下: ```bash case 變量 in value1) command ;; value2) command ;; *) command ;; esac ``` 結合執行shell腳本時傳入的參數,可以實現功能的切換: ```bash #!/bin/bash case $1 in start|s) ## |表示or,在這里表示匹配start或s均可 echo service is running ;; stop) echo service is stoped ;; reload) echo service is reload ;; *) echo xxxxx ;; esac ``` #### for循環 語法如下: ``` for 變量名 in 循環的條件; do command done ``` ##### 循環條件 - 數字遞進:`((i=1;i<=10;i++))` - 列舉一組字符串或數字,以空格分隔:`1 2 3 aaa bbb` - 命令執行的結果: ```bash for i in `ls`; do echo $i is file name\! done ``` - 變量的值: ```bash list="rootfs usr data data2" for i in $list; do echo $i is appoint done ``` - 執行腳本時傳入的參數: ```bash #!/bin/bash echo "number of arguments is $#" # $#表示參數的個數 echo "What you input is: " for argument in "$@"; do # $@表示參數列表,此處也可以使用$*代替,$*則把所有的參數當作一個字符串 echo "$argument" done ``` #### while循環 語法: ``` while [循環(判斷)的條件]; do command done ``` 注意此處的***循環(判斷)的條件***與`if`語句中的判斷條件是一樣的。 #### 函數 ##### 函數定義語法: ```bash function 函數名() { command [return] # 可return也可不return } ``` ##### 函數的調用方法是: ```bash #!/bin/bash function show() { echo "hello , you are calling the function" } echo "first time call the function" show echo "second time call the function" show ``` ##### 如函數需要傳入參數,則使用$1、$2……等取用: ```bash #!/bin/bash function show() { echo "hello , you are calling the function $1" } echo "first time call the function" show first # 輸出hello , you are calling the function first echo "second time call the function" show second # 輸出hello , you are calling the function second ``` ##### 函數中的關鍵字“return”可以放到函數體的任意位置,通常用于返回某些值,Shell在執行到return之后,就停止往下執行,返回到主程序的調用行,return的返回值只能是0~256之間的一個整數,返回值將保存到變量“$?”中。 ``` #!/bin/bash function test() { return 0 } test echo "$?" # 輸出0 ``` ##### 如果函數在另外一個文件中,我們該怎么調用它呢? 我們可以使用`source`命令,比如 show 函數寫在了function.sh里面了: ```bash source function.sh show ``` ##### 函數的變量作用域 默認情況下,變量具有全局作用域,如果想把它設置為局部作用域,可以在其前加入local 例如: ```bash local a=hello ``` 使用局部變量,使得函數在執行完畢后,自動釋放變量所占用的內存空間,從而減少系統資源的消耗,在運行大型的程序時,定義和使用局部變量尤為重要。 ##### 函數的嵌套 函數可以進行嵌套,實例: ```bash #!/bin/bash function first() { function second() { function third() { echo "------this is third" } echo "this is the second" third } echo "this is the first" second } echo "start..." first ``` #### shell腳本中的中斷和繼續 ##### break 與其它程序語言一樣,`break`是用來跳出當前的循環的,`break`后可加數字,如`break 2`表示跳出兩層的循環。 ##### continue 與其它程序語言一樣。 ##### exit 退出腳本,或者更準確地說,是退出當前運行腳本的shell(既然運行環境關閉了,那么腳本當然也不能繼續執行下去了)。 在函數中使用`exit`,是會退出整個腳本的,因此若只是想退出函數,請使用`return`。 `exit`后可接數字作為狀態碼,如`exit 0`;一般來說,**0**表示腳本執行成功,其它狀態碼則表示各種可能的異常情況 ## 別名 我們可以通過`alias`命令把一個常用的并且很長的指令另取名為一個簡單易記的指令;如果不想用了,還可以使用`unalias`來取消。 - 使用`alias`命令,可以列出系統當前所有的別名。 - 使用`alias [命令別名]=['具體的命令']`可以自定義別名,例如:`alias aming='pwd'`。 - 使用`unalias`可以取消別名,例如`unalias aming`。 ## 重定向 重定向分為“輸入重定向”和“輸出重定向”,重定向一般通過在命令間插入特定的符號來實現。 - `command1 > file1`,這個命令執行command1然后將執行后輸出的內容存入file1。注意任何file1內的已經存在的內容將被新內容替代。如果要將新內容添加在文件末尾,請使用>>操作符。 - `command1 < file1`,執行command1,使用file1作為用來替代鍵盤的輸入源。 - `command1 < infile > outfile`,同時替換輸入和輸出,執行command1,從文件infile讀取內容,然后將輸出寫入到outfile中。 另外,上述的“輸出內容”僅指命令執行的結果,若命令執行中出現錯誤,則錯誤信息需要另行處理: - `command1 2> file1`,執行command1,然后將標準錯誤輸出重定向到文件file1。 - 另外一個很有用的功能是將標準錯誤輸出融合到標準輸出中去,這樣錯誤信息可以和其他普通的輸出信息一起處理。例如:`command > file 2>&1`,這表示將command執行后的結果與錯誤信息均寫入到file里。 ## 管道符 管道符的標識為`|`,它用于將前一個指令的輸出作為后一個指令的輸入,格式如下:`command1 | command2`,舉例說明:`yum list | grep zip | head -n 5`。
                  <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>

                              哎呀哎呀视频在线观看