Bash開始使用Bash


版本

發布日期
0.99 1989年6月8日
1.01 1989年6月23日
2.0 1996-12-31
2.02 1998年4月20日
2.03 1999年2月19日
2.04 2001-03-21
2.05b以上 2002-07-17
3.0 2004-08-03
3.1 2005-12-08
3.2 2006-10-11
4 2009-02-20
4.1 2009-12-31
4.2 2011-02-13
4.3 2014年2月26日
4.4 2016年9月15日

處理命名參數

#!/bin/bash

deploy=false
uglify=false

while (( $# > 1 )); do case $1 in
   --deploy) deploy="$2";;
   --uglify) uglify="$2";;
   *) break;
 esac; shift 2
done

$deploy && echo "will deploy... deploy = $deploy"
$uglify && echo "will uglify... uglify = $uglify"

# how to run
# chmod +x script.sh
# ./script.sh --deploy true --uglify false
 

你好,世界

互動殼牌

Bash shell通常以交互方式使用它允許您輸入和編輯命令,然後在按Return鍵時執行它們。許多基於Unix和類Unix操作系統使用Bash作為其默認shell(特別是Linux和macOS)。終端在啟動時自動進入交互式Bash shell進程。

鍵入以下內容輸出Hello World

echo "Hello World"
#> Hello World  # Output Example
 

筆記

  • 您只需在終端中鍵入shell的名稱即可更改shell。例如: shbash

  • echo 是一個Bash內置命令,它將接收的參數寫入標準輸出。默認情況下,它會在輸出中附加換行符。


非交互式外殼

Bash shell也可以從腳本非交互式運行,使shell不需要人工交互。交互行為和腳本行為應該是相同的 - 這是Unix V7 Bourne shell和傳遞Bash的重要設計考慮因素。因此,可以在命令行中執行的任何操作都可以放在腳本文件中以供重用。

請按照以下步驟創建Hello World 腳本:

  1. 創建一個名為hello-world.sh 的新文件

    touch hello-world.sh
     
  2. 通過運行chmod +x hello-world.sh 使腳本可執行

  3. 添加此代碼:

    #!/bin/bash
    echo "Hello World"
     

    第1行:腳本的第一行必須以字符序列#! 開頭#! ,簡稱shebang 1 。 shebang指示操作系統運行/bin/bash ,即Bash shell,將腳本的路徑作為參數傳遞給它。

    例如/bin/bash hello-world.sh

    第2行 :使用echo 命令將Hello World 寫入標準輸出。

  1. 使用以下命令之一從命令行執行hello-world.sh 腳本:

    • ./hello-world.sh - 最常用,推薦
    • /bin/bash hello-world.sh
    • bash hello-world.sh - 假設/bin$PATH
    • sh hello-world.sh

對於實際的生產用途,你會省略.sh 擴展名(無論如何都會誤導,因為這是一個Bash腳本,而不是sh 腳本),並且可能會將文件移動到PATH 的目錄中,以便無論是否可以使用它。您當前的工作目錄,就像系統命令,如catls

常見錯誤包括:

  1. 忘記對文件應用執行權限,即chmod +x hello-world.sh ,導致chmod +x hello-world.sh 的輸出./hello-world.sh: Permission denied

  2. 在Windows上編輯腳本,這會產生Bash無法處理的錯誤行結束字符。

    常見的症狀是: command not found 在回車將光標強製到行首的位置: command not found ,覆蓋錯誤消息中冒號前的文本。

    可以使用dos2unix 程序修復腳本。

    使用示例: dos2unix hello-world.sh

    dos2unix 內聯編輯文件。

  3. 使用sh ./hello-world.sh ,沒有意識到bashsh 是具有不同特徵的不同shell(儘管由於Bash是向後兼容的,因此相反的錯誤是無害的)。

    無論如何,僅僅依靠腳本的shebang行比在每個腳本的文件名之前顯式寫bashsh (或pythonperlawkruby 或...)更為可取。

    為了使腳本更具可移植性而使用的常見shebang行是使用#!/usr/bin/env bash 而不是硬編碼Bash的路徑。這樣, /usr/bin/env 必須存在,但除此之外, bash 只需要在你的PATH 。在許多系統上, /bin/bash 不存在,你應該使用/usr/local/bin/bash 或其他一些絕對路徑;這種變化避免了弄清楚細節。


1 也稱為sha-bang,hashbang,pound-bang,hash-pling。

“調試”模式下的Hello World

$ cat hello.sh 
#!/bin/bash 
echo "Hello World"
$ bash -x hello.sh 
+ echo Hello World
Hello World
 

-x 參數使您可以遍歷腳本中的每一行。這裡有一個很好的例子:

$ cat hello.sh
#!/bin/bash 
echo "Hello World\n" 
adding_string_to_number="s"
v=$(expr 5 + $adding_string_to_number) 

$ ./hello.sh 
Hello World

expr: non-integer argument
 

以上提示錯誤不足以跟踪腳本;但是,使用以下方法可以更好地了解在腳本中查找錯誤的位置。

$ bash -x hello.sh 
+ echo Hello World\n
Hello World

+ adding_string_to_number=s
+ expr 5 + s
expr: non-integer argument
+ v=
 

Hello World使用變量

使用以下內容創建一個名為hello.sh 的新文件,並使用chmod +x hello.sh 為其授予可執行權限。

執行/運行: ./hello.sh

#!/usr/bin/env bash

# Note that spaces cannot be used around the `=` assignment operator
whom_variable="World"

# Use printf to safely output the data
printf "Hello, %s\n" "$whom_variable"
#> Hello, World
 

這將在執行時將Hello, World 打印到標準輸出。

要告訴bash你需要非常具體的腳本,通過將其指向包含目錄,通常使用./ 如果它是你的工作目錄,在哪裡. 是當前目錄的別名。如果未指定目錄, bash 嘗試在$PATH 環境變量中包含的某個目錄中找到該腳本。


下面的代碼接受一個參數$1 ,這是第一個命令行參數,並在一個格式化的字符串中輸出它,在Hello,

執行/運行: ./hello.sh World

#!/usr/bin/env bash
printf "Hello, %s\n" "$1"
#> Hello, World
 

值得注意的是, $1 必須以雙引號引用,而不是單引號。 "$1" 根據需要擴展到第一個命令行參數,而'$1' 計算為文字字符串$1

安全說明:
閱讀忘記在bash shell中引用變量的安全含義,以了解將變量文本放在雙引號內的重要性。

用戶輸入的Hello World

以下將提示用戶輸入,然後將該輸入作為字符串(文本)存儲在變量中。然後使用該變量向用戶發送消息。

#!/usr/bin/env bash
echo  "Who are you?"
read name
echo "Hello, $name."
 

命令read 這裡從標準輸入讀取數據的一行入變量name 。然後使用$name 引用它,並使用echo 打印到標準輸出。

輸出示例:

$ ./hello_world.sh
Who are you?
Matt
Hello, Matt.
 

在這裡,用戶輸入了名稱“Matt”,此代碼用於表示Hello, Matt.

如果要在打印時將某些內容附加到變量值,請在變量名稱周圍使用大括號,如下例所示:

#!/usr/bin/env bash
echo  "What are you doing?"
read action
echo "You are ${action}ing."
 

輸出示例:

$ ./hello_world.sh
What are you doing?
Sleep
You are Sleeping.
 

在此處,當用戶輸入動作時,在打印時將“ing”附加到該動作。

在字符串中引用的重要性

引用對於bash中的字符串擴展很重要。通過這些,您可以控制bash如何解析和擴展字符串。

引用有兩種類型:

  • 使用雙引號:“
  • 使用單引號:'

如果你想bash擴展你的論點,你可以使用弱報價

#!/usr/bin/env bash
world="World"
echo "Hello $world"
#> Hello World
 

如果您不想bash擴展您的參數,可以使用強引號

#!/usr/bin/env bash
world="World"
echo 'Hello $world'
#> Hello $world
 

您還可以使用escape來防止擴展:

#!/usr/bin/env bash
world="World"
echo "Hello \$world"
#> Hello $world
 

有關初學者詳細信息以外的更多詳細信息,您可以在此處繼續閱讀。

查看Bash內置函數的信息

help <command>
 

這將顯示指定內置的Bash幫助(手動)頁面。

例如, help unset 將顯示:

unset: unset [-f] [-v] [-n] [name ...]
   Unset values and attributes of shell variables and functions.

   For each NAME, remove the corresponding variable or function.

   Options:
     -f    treat each NAME as a shell function
     -v    treat each NAME as a shell variable
     -n    treat each NAME as a name reference and unset the variable itself
       rather than the variable it references

   Without options, unset first tries to unset a variable, and if that fails,
   tries to unset a function.

   Some variables cannot be unset; also see `readonly'.

   Exit Status:
   Returns success unless an invalid option is given or a NAME is read-only.
 

要查看包含簡短描述的所有內置列表,請使用

help -d