9 個 Bash 腳本示例讓您開始使用 Linux
已發表: 2022-07-05如果您剛開始在 Linux 上編寫 Bash 腳本,那麼紮實掌握基礎知識將對您有利。 它們是更深入的知識和更高的腳本技能的基礎。
記住,讓你的腳本可執行
要讓 shell 執行腳本,腳本必須具有可執行文件權限集。 沒有這個,你的腳本只是一個文本文件。 有了它,它仍然是一個文本文件,但 shell 知道它包含指令,並會在腳本啟動時嘗試執行它們。
編寫腳本的全部意義在於它們可以運行,所以第一步是要知道如何讓 Linux 知道你的腳本應該被認為是可執行的。
chmod
命令讓我們設置文件權限。 可以使用 +x 標誌設置執行權限。
chmod +x script1.sh
您需要對每個腳本執行此操作。 將“script1.sh”替換為您的腳本名稱。
1. 奇怪的第一行是什麼?
腳本的第一行告訴 shell 應該調用哪個解釋器來運行該腳本。 第一行必須以 shebang 開頭,“#!”,也稱為 hashbang。 這 ”#!” 告訴 shell 這一行包含腳本所針對的解釋器的路徑和名稱。
這很重要,因為如果您編寫了要在 Bash 中運行的腳本,您不希望它被不同的 shell 解釋。 可能存在不兼容的情況。 與大多數 shell 一樣,Bash 有自己的語法和功能,而其他 shell 沒有,或者以不同的方式實現。
當您運行腳本時,當前 shell 打開腳本並確定應該使用哪個 shell 或解釋器來執行該腳本。 然後它啟動那個 shell 並將腳本傳遞給它。
#!/bin/bash echo 在 $SHELL 中運行
該腳本的第一行可以讀作“使用位於 /bin/bash 的解釋器來運行此腳本”。
腳本中唯一的一行將$SHELL
環境變量中保存的值寫入終端屏幕。 這證實了使用 Bash 執行腳本。
./script1.sh
作為一個小技巧,我們可以證明腳本被傳遞給我們選擇的任何解釋器。
#!/bin/cat 所有文本行都傳遞給 cat 命令 並打印在終端窗口中。 那包含著 舍邦線。
腳本2.sh
此腳本由當前 shell 啟動並傳遞給cat
命令。 cat
命令“運行”腳本。
像這樣編寫你的 shebangs 假設你知道 shell 或其他解釋器在目標機器上的位置。 99% 的情況下,這都很好。 但是有些人喜歡對沖他們的賭注並像這樣寫他們的shebangs:
#!/usr/bin/env bash echo 在 $SHELL 中運行
腳本3.sh
當腳本啟動時,shell 會搜索命名 shell 的位置。 如果 shell 恰好位於非標準位置,這種方法可以避免“錯誤解釋器”錯誤。
別聽,他在說謊!
在 Linux 中,總是有不止一種方法可以給貓剝皮或證明作者的錯誤。 完全符合事實的是,有一種方法可以在沒有 shebang 的情況下運行腳本,並且不讓它們可執行。
如果您啟動要執行腳本的 shell 並將腳本作為命令行參數傳遞,則 shell 將啟動並運行腳本——無論它是否可執行。 因為您在命令行上選擇了 shell,所以不需要 shebang。
這是整個腳本:
echo "我被處決了" $SHELL
我們將使用ls
來查看該腳本確實不可執行,並使用該腳本的名稱啟動 Bash:
ls
bash script4.sh
還有一種方法可以讓當前shell 運行腳本,而不是專門為執行腳本而啟動的 shell。 如果使用source
命令,可以縮寫為單個句點“ .
“,您的腳本由您當前的 shell 執行。
因此,要在沒有 shebang、沒有可執行文件權限且不啟動另一個 shell 的情況下運行腳本,您可以使用以下任一命令:
源腳本4.sh
. 腳本4.sh
儘管這是可能的,但不建議將其作為一般解決方案。 有缺點。
如果腳本不包含 shebang,則您無法判斷它是為哪個 shell 編寫的。 一年後你會記得嗎? 如果腳本沒有設置可執行權限, ls
命令不會將其識別為可執行文件,也不會使用顏色將腳本與純文本文件區分開來。
相關:命令行:為什麼人們仍然為它們煩惱?
2. 打印文本
向終端寫入文本是一項常見要求。 一點視覺反饋會有很長的路要走。
對於簡單的消息, echo
命令就足夠了。 它允許對文本進行一些格式化,也允許您使用變量。
#!/bin/bash echo 這是一個簡單的字符串。 echo "這是一個包含'單引號'的字符串,所以它用雙引號括起來。" echo "這將打印用戶名:" $USER echo -e "-e 選項讓我們使用\n格式化指令\n分割字符串。"
./script5.sh
printf
命令為我們提供了更大的靈活性和更好的格式化功能,包括數字轉換。
此腳本使用三個不同的數字基數打印相同的數字。 十六進製版本也被格式化為以大寫形式打印,前導零和三位數的寬度。
#!/bin/bash printf "十進制:%d,八進制:%o,十六進制:%03X\n" 32 32 32
./script6.sh
請注意,與echo
不同,您必須告訴printf
以“ \n
”標記開始新行。
3. 創建和使用變量
變量允許您在程序中存儲值並操作和使用它們。 您可以創建自己的變量或使用環境變量作為系統值。
#!/bin/bash millennium_text="千禧年以來的歲月:" current_time=$(日期'+%H:%M:%S') todays_date=$( 日期 '+%F' ) 年=$(日期'+%Y') echo "當前時間:" $current_time echo "今天的日期:" $todays_date years_since_Y2K=$(( 年 - 2000 )) 迴聲 $millennium_text $years_since_Y2K
此腳本創建一個名為millennium_text
的字符串變量。 它包含一行文本。
然後它創建三個數值變量。
-
current_time
變量被初始化為腳本執行的時間。 -
todays_date
變量設置為腳本運行的日期。 -
year
變量保存當前年份。
要訪問存儲在變量中的值,請在其名稱前加上美元符號“$”。
./script7.sh
該腳本打印時間和日期,然後計算自千禧年以來已經過去了多少年,並將其存儲在years_since_Y2K
變量中。
最後,它打印包含在millennium_text
變量中的字符串和存儲在years_since_Y2K
中的數值。
相關:如何在 Bash 中使用變量
4. 處理用戶輸入
要允許用戶輸入腳本將使用的值,您需要能夠捕獲用戶的鍵盤輸入。 Bash read
命令允許 ut 做到這一點。 這是一個簡單的例子。
#!/bin/bash echo "輸入一個數字並點擊\"Enter\"" 讀取用戶編號 1; echo "輸入另一個數字並點擊 \"Enter\"" 讀取用戶編號2; printf "你輸入了:%d 和 %d\n" $user_number1 $user_number2 printf "把它們加在一起:%d\n" $((user_number1 + user_number2))
該腳本提示輸入兩個數字。 它們從鍵盤讀取並存儲在兩個變量user_number1
和user_number2
中。
該腳本將數字打印到終端窗口,將它們加在一起,然後打印總數。
./script8.sh
我們可以使用-p
(提示)選項將提示組合到read
命令中。
#!/bin/bash read -p "輸入一個數字並點擊\"Enter\" " user_number1; read -p "輸入另一個數字並點擊\"Enter\" " user_number2; printf "你輸入了:%d 和 %d\n" $user_number1 $user_number2 printf "把它們加在一起:%d\n" $((user_number1 + user_number2))
這使事情更整潔,更容易閱讀。 易於閱讀的腳本也更易於調試。
./script9.sh
該腳本現在的行為略有不同。 用戶輸入與提示位於同一行。
要捕獲鍵盤輸入而不將其回顯到終端窗口,請使用-s
(靜默)選項。
#!/bin/bash read -s -p "輸入您的密碼並點擊 \"Enter\" " secret_PIN; printf "\nShhh ... 它是 %d\n" $secret_PIN
./script10.sh
輸入值被捕獲並存儲在一個名為secret_PIN
的變量中,但是當用戶鍵入它時它不會回顯到屏幕上。 之後你用它做什麼取決於你。
5.接受參數
有時接受用戶輸入作為命令行參數比讓腳本等待輸入更方便。 將值傳遞給腳本很容易。 它們可以在腳本中被引用,就像它們是任何其他變量一樣。
第一個參數變為變量$1
,第二個參數變為變量$2
,依此類推。 變量$0
始終保存腳本的名稱,變量$#
保存命令行中提供的參數數量。 變量$@
是一個包含所有命令行參數的字符串。
#!/bin/bash printf "這個腳本被調用:%s\n" $0 printf "你使用了 %d 個命令行參數\n" $# # 循環遍歷變量 對於“$@”中的參數; 做 迴聲“$參數” 完畢 echo "參數 2 是:" $2
該腳本使用$0
和$#
來打印一些信息。 然後使用?@
循環所有命令行參數。 它使用$2
來展示如何訪問單個特定的參數值。
./script11.sh
將幾個單詞用引號“””括起來,將它們組合成一個參數。
6. 從文件中讀取數據
知道如何從文件中讀取數據是一項很棒的技能。 我們可以在 Bash 中使用 while 循環來做到這一點。
#!/bin/bash 行數=0 而 IFS='' 讀取 -r LinefromFile || [[ -n "${LinefromFile}" ]]; 做 ((線數++)) echo "讀取行 $LineCount: ${LinefromFile}" 完成 <"$1"
我們將希望腳本處理的文件的名稱作為命令行參數傳遞。 這將是唯一的參數,因此在腳本中$1
將保存文件名。 我們將該文件重定向到while
循環中。
while
循環使用IFS=''
賦值將內部字段分隔符設置為空字符串。 這可以防止read
命令在空白處拆分行。 只有行尾的回車才被認為是真正的行尾。
[[ -n "${LinefromFile}" ]]
子句滿足文件中最後一行不以回車符結尾的可能性。 即使沒有,最後一行也將被正確處理並被視為常規的 POSIX 兼容行。
./script12.sh 閃爍.txt
7. 使用條件測試
如果您希望腳本針對不同的條件執行不同的操作,則需要執行條件測試。 雙括號測試語法起初提供了大量的選項。
#!/bin/bash 價格=$1 如果 [[ 價格 -ge 15 ]]; 然後 迴聲“太貴了。” 別的 迴聲“買!” 菲
Bash 提供了一整套比較運算符,可讓您確定諸如文件是否存在、是否可以讀取文件、是否可以寫入文件以及目錄是否存在等內容。
它還對等於-qe
、大於-gt
、小於或等於-le
等進行了數值測試,儘管您也可以使用熟悉的==
、 >=
、 <=
表示法。
./script13.sh 13
./script13.sh 14
./script13.sh 15
./script13.sh 16
8. for 循環的威力
一遍又一遍地重複動作最好使用循環來完成。 for
循環允許您多次運行循環。 這可能達到一個特定的數字,或者可能直到循環通過項目列表。
#!/bin/bash 對於 (( i=0; i<=$1; i++ )) 做 echo "C 風格的 for 循環:" $i 完畢 對於我在 {1..4} 做 echo "For 循環範圍:" $i 完畢 對於 i 在 "零" "一" "二" "三" 做 echo "帶有單詞列表的 For 循環:" $i 完畢 網站="如何極客" 對於我在 $website 做 echo "帶有單詞集合的 For 循環:" $i 完畢
所有這些循環都是for
循環,但它們使用不同類型的循環語句和數據。
./script14.sh 3
第一個循環是經典的 C 風格for
循環。 循環計數器i
初始化為零,並隨著循環的每個循環遞增。 當i
的值小於或等於$1
中保存的值時,循環將繼續運行。
第二個循環處理從 1 到 4 的數字範圍。第三個循環處理一個單詞列表。 雖然有更多的詞要處理,但循環會不斷重複。
最後一個循環遍歷字符串變量中的單詞列表。
9. 功能
函數允許您將代碼段封裝到命名例程中,這些例程可以從腳本中的任何位置調用。
假設我們希望從文件中讀取行的腳本對每一行進行某種處理。 將該代碼包含在函數中會很方便。
#!/bin/bash 行數=0 函數 count_words() { printf "%d 行中的 %d 個單詞\n" $(echo $1 | wc -w) $2 } 而 IFS='' 讀取 -r LinefromFile || [[ -n "${LinefromFile}" ]]; 做 ((線數++)) count_words "$LinefromFile" $LineCount 完成 <"$1" count_words "這不在循環中" 99
我們通過添加一個名為count_words
的函數來修改我們的文件讀取程序。 它是在我們需要使用它之前定義的。
函數定義以單詞function
開頭。 接下來是我們函數的唯一名稱,後跟括號“ ()
”。 函數的主體包含在大括號“{}”中。
函數定義不會導致任何代碼被執行。 在調用函數之前,函數中的任何內容都不會運行。
count_words
函數打印一行文本中的單詞數和行號。 這兩個參數被傳遞到函數中,就像參數被傳遞到腳本中一樣。 第一個參數成為函數變量$1
,第二個參數成為函數變量$2
,依此類推。
while
循環從文件中讀取每一行並將其與行號一起傳遞給count_words
函數。 為了表明我們可以從腳本中的不同位置調用該函數,我們在while
循環之外再次調用它。
./script15.sh 閃爍.txt
不要害怕學習曲線
腳本是有益的和有用的,但很難進入。 一旦掌握了一些可重用的技術,您將能夠相對輕鬆地編寫有價值的腳本。 然後您可以查看更高級的功能。
在跑步之前先步行,並花時間享受旅程。
相關: 10 個適合初學者的基本 Linux 命令