bash入門教程

jopen 10年前發布 | 16K 次閱讀 Linux Bash
shell的種類:
sh  - Bourne shell
csh or tcsh - C shell
korn - Korn shell
bash - GNU Bourne-Again shell

1.最簡單的列子
例子
#!/bin/bash  
# This is a very simple example echo Hello World
echo Hello World

解釋:
在 BASH 中 第一行的 "#!" 及后面的 "/bin/bash" 就表明該文件是一個 BASH 程序,需要由 /bin 目錄下的 bash 程序來解釋執行。
在 BASH 程序中從“#”號(注意:后面緊接著是“!”號的除外)開始到行尾的多有部分均被看作是程序的注釋
echo 語句的功能是把 echo 后面的字符串輸出到標準輸出中去

執行該程序:
1.$ bash hello 或 
   $ sh hello 
2.將 hello 文件改為可以執行的文件,然后直接運行它,此時由于 hello 文件第一行的 "#! /bin/bash" 的作用,系統會自動用/bin/bash 程序去解釋執行 hello 文件的:
$ chmod u+x hello 
$ ./hello

2.關于輸入、輸出和錯誤輸出 
在 Linux 系統中:
標準輸入(stdin)默認為鍵盤輸入;
標準輸出(stdout)默認為屏幕輸出;
標準錯誤輸出(stderr)默認也是輸出到屏幕(上面的 std 表示 standard)。

$ ls > ls_result 
$ ls -l >> ls_result 
ls 命令的結果輸出 重定向到 ls_result 文件中和 追加到 ls_result 文件中,而不是輸出到屏幕上。
">"就是輸出(標準輸出和標準錯誤輸出)重定向的代表符號,連續兩個 ">" 符號,即 ">>" 則表示不清除原來的而追加輸出

$ find /home -name lost* 2> err_result 
這個命令在 ">" 符號之前多了一個 "2","2>" 表示將標準錯誤輸出重定向。由于 /home 目錄下有些目錄由于權限限制不能訪問,因此會產生一些標準錯誤輸出被存放在 err_result 文件中

$ find /home -name lost* > all_result 2>& 1 
首先將標準錯誤輸出也重定向到標準輸出中,再將標準輸出重定向到 all_result 這個文件中。這樣我們就可以將所有的輸出都存儲到文件中了
更簡單的寫法:
$ find /home -name lost* >& all_result 
可以讓你避開眾多無用出錯信息的干擾:
$ find /home -name lost* 2> /dev/null

另外一個非常有用的重定向操作符是 "-"
$ (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xvfp -)  
該命令表示把 /source/directory 目錄下的所有文件通過壓縮和解壓,快速的全部移動到 /dest/directory 目錄下去

3.變量
例子:
#!/bin/bash  
# give the initialize value to 
STR STR="Hello World"  
echo $STR

注意點:
1,變量賦值時,'='左右兩邊都不能有空格;
2,BASH 中的語句結尾不需要分號(";"); 
3,除了在變量賦值和在FOR循環語句頭中,BASH 中的變量使用必須在變量前加"$"符號,
4,由于 BASH 程序是在一個新的進程中運行的,所以該程序中的變量定義和賦值不會改變其他進程或原始 Shell 中同名變量的值,也不會影響他們的運行。

一個變量即可以被定義為一個字符串,也可以被再定義為整數。如果對該變量進行整數運算,他就被解釋為整數;如果對他進行字符串操作,他就被看作為一個字符串
例子:
#!/bin/bash  
x=1999  
let "x = $x + 1"  
echo $x  
x="olympic'"$x  
echo $x

整數運算一般通過 let 和 expr 這兩個指令來實現,如對變量 x 加 1 可以寫作:let "x = $x + 1" 或者 x=`expr $x + 1`

對應的操作
整數操作
字符串操作
相同
-eq
=
不同
-ne
!=
大于
-gt
>
小于
-lt
<
大于或等于
-ge

小于或等于
-le

為空

-z
不為空

-n

BASH 中用于判斷文件屬性的操作符:
運算符
含義( 滿足下面要求時返回 TRUE )
-e file
文件 file 已經存在
-f file
文件 file 是普通文件
-s file
文件 file 大小不為零  
-d file
文件 file 是一個目錄   
-r file
文件 file 對當前用戶可以讀取   
-w file
文件 file 對當前用戶可以寫入
-x file
文件 file 對當前用戶可以執行   
 -g file
文件 file 的 GID 標志被設置   
-u file
文件 file 的 UID 標志被設置   
-O file
 文件 file 是屬于當前用戶的   
-G file
文件 file 的組 ID 和當前用戶相同
file1 -nt file2   
文件 file1 比 file2 更新
file1 -ot file2 
文件 file1 比 file2 更老   

局部變量
在變量首次被賦初值時加上 local 關鍵字就可以聲明一個局部變量
例子:
#!/bin/bash  
HELLO=Hello  
function hello {  
   local HELLO=World    
  echo $HELLO 
 }  
echo $HELLO  
hello  
echo $HELLO 
該程序的執行結果是: 
Hello 
World 
Hello

4.基本流程控制語法
if...then...else 
if 語句用于判斷和分支,其語法規則和 C 語言的 if 非常相似。其幾種基本結構為:  
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

注:如果你將 if 和 then 簡潔的寫在一行里面,就必須在 then 前面加上分號,如:if [ expression ]; then ... 

for循環
for $var in [list] 
do 
  statments 
done
注:do 和 for 被寫在同一行,必須在 do 前面加上 ";"。如: for $var in [list]; do

例子:
#!/bin/bash   
for day in Sun Mon Tue Wed Thu Fri Sat  
do  
  echo $day 
done

如果列表被包含在一對雙引號中,則被認為是一個元素
例子:
#!/bin/bash   
for day in  “Sun Mon Tue Wed Thu Fri Sat “ 
do  
  echo $day 
done

如果寫成 for day 而沒有后面的 in [list] 部分,則 day 將取遍命令行的所有參數
例子:
#!/bin/bash   
for param  
do  
  echo $param  
done   
exit 0 

while
while [ condition ] 
do 
  statments 
done

util
until [ condition is TRUE ] 
do 
  statments 
done 

case
case "$var" in  
    condition1 )   
         statments1;;  
    condition2 )  
         statments2;;
      ...  
     * ) 
          default statments;; 
esac

例子
#!/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 語句表示從鍵盤上讀取輸入

支持break/continue
你懂得

5.函數
function my_funcname { 
   code block 
 或者  
my_funcname() {
   code block 
BASH 中函數參數的定義并不需要在函數定義處就制定,而只需要在函數被調用時用 BASH 的保留變量 $1 $2 ... 來引用就可以了;
BASH 的返回值可以用 return 語句來指定返回一個特定的整數,如果沒有 return 語句顯式的返回一個返回值,則返回值就是該函數最后一條語句執行的結果(一般為 0,如果執行失敗返回錯誤碼)。
函數的返回值在調用該函數的程序體中通過 $? 保留字來獲得。
例子
#!/bin/bash
square() {
 let "res = $1 * $1"
 return $res  
}
square $1
result=$?
echo $result
exit 0


6.BASH 中的特殊保留字
保留變量
$IFS  這個變量中保存了用于分割輸入參數的分割字符,默認是空格。  
$HOME  這個變量中存儲了當前用戶的根目錄路徑。  
$PATH  這個變量中存儲了當前 Shell 的默認路徑字符串。  
$PS1  表示第一個系統提示符。  
$PS2  表示的二個系統提示符。 
$PWD  表示當前工作路徑。  
$EDITOR 表示系統的默認編輯器名稱。  
$BASH  表示當前 Shell 的路徑字符串。 
$0, $1, $2, ...  表示系統傳給腳本程序或腳本程序傳給函數的第0個、第一個、第二個等參數。 
$#   表示腳本程序的命令參數個數或函數的參數個數。 
$$   表示該腳本程序的進程號,常用于生成文件名唯一的臨時文件。  
$?   表示腳本程序或函數的返回狀態值,正常為 0,否則為非零的錯誤號。
$*   表示所有的腳本參數或函數參數。 
$@   和 $* 涵義相似,但是比 $* 更安全。 
$!   表示最近一個在后臺運行的進程的進程號。

隨機數
$RANDOM:隨機產生一個大小在 1 到 65536 之間的整數。

變量的特殊操作
${var-default} 表示如果變量 $var 還沒有設置,則保持 $var 沒有設置的狀態,并返回后面的默認值 default。 
${var=default} 表示如果變量 $var 還沒有設置,則取后面的默認值 default。  
${var+otherwise} 表示如果變量 $var 已經設置,則返回 otherwise 的值,否則返回空( null )。 
${var?err_msg} 表示如果變量 $var 已經設置,則返回該變量的值,否則將后面的 err_msg 輸出到標準錯誤輸出上。
這些用法主要用于從文件路徑字符串中提取有用信息: 
${var#pattern}, ${var##pattern} 用于從變量 $var 中剝去最短(最長)的和 pattern 相匹配的最左側的串。 
${var%pattern}, ${var%%pattern} 用于從變量 $var 中剝去最短(最長)的和 pattern 相匹配的最右側的串。 
另外 BASH 2 中還加入下面一些操作: 
${var:pos} 表示去掉變量 $var 中前 pos 個字符。 
${var:pos:len} 表示變量 $var 中去掉前 pos 個字符后的剩余字符串的前 len 個字符。 
${var/pattern/replacement} 表示將變量 $var 中第一個出現的 pattern 模式替換為 replacement 字符串。 
${var//pattern/replacement} 表示將變量 $var 中出現的所有 pattern 模式全部都替換為 replacment 字符串。


7.BASH 中的其他高級問題
BASH 中對返回值的處理
無論是在 Shell 中對 BASH 腳本返回值的處理,還是在腳本中對函數返回值的處理,都是通過 "$?" 系統變量來獲得。
BASH 要求返回值必須為一個整數,不能用 return 語句返回字符串變量

用 BASH 設計簡單用戶界面
select var in [list] 
do 
 statments use $var 
done
BASH 會將 [list] 中的所有項加上數字列在屏幕上等待用戶選擇,在用戶作出選擇后,變量 $var 中就包含了那個被選中的字符串
例子
#!/bin/bash   
OPTIONS="Hello Quit"  
select opt in $OPTIONS; do  
     if [ "$opt" = "Quit" ]; then    
        echo done    
        exit  
     elif [ "$opt" = "Hello" ]; then    
            echo Hello World    
        else     
            clear  
            echo bad option   
    fi  
done   
exit 0

BASH 程序的調試
用 bash -x bash-script 命令,可以查看一個出錯的 BASH 腳本到底錯在什么地方,可以幫助程序員找出腳本中的錯誤。 
另外用 trap 語句可以在 BASH 腳本出錯退出時打印出一些變量的值,以供程序員檢查。
trap 語句必須作為繼 "#!/bin/bash" 后的第一句非注釋代碼,一般 trap 命令被寫作: trap 'message $checkvar1 $checkvar2' EXIT 
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!