大家好,很高興見到你們回來!對於我們程式設計師來說,深入研究 Bash 腳本的世界確實很重要。這一切都是為了建立腳本,本質上是小程序,來自動執行我們每天面臨的那些繁瑣、重複的操作。我們無需一遍又一遍地手動執行命令,而是使用腳本來簡化它們。
它透過自動化日常事務讓我們的生活變得更輕鬆,讓我們專注於開發中更令人興奮的方面。
在接下來的幾分鐘內,我們將透過實際範例探索 Bash 腳本的基礎知識。最後,您將對如何簡化工作流程和提高工作效率有深入的理解。
你興奮嗎?
有任何先決條件嗎?
如果您是 Windows 用戶,則需要設定 WSL 以在您的系統上使用 Linux。您可以在此處了解更多資訊。
注意:在本文中,術語「shell 腳本」和「Bash 腳本」可互換使用。 Bash 是最常見的 shell,就本次討論的目的而言,它們可以被視為相同的。
Bash 腳本到底是什麼?
可以將其視為建立一個小程式來自動執行您通常手動執行的任務。這些腳本是純文字文件,包含您通常在命令列中輸入的命令。舉個例子,假設您需要將資料夾 A 中的所有 100 個檔案複製到資料夾 B,那麼這個任務真的很無聊且重複,因此您可以編寫一個 bash 腳本將所有檔案從 A 複製到 B。
我們為什麼需要它?
我們需要 Bash 腳本,因為它可以節省我們的時間和精力。你可以把它想像成擁有一個可以處理所有無聊、重複任務的助手,這樣你就可以專注於有趣的事情。是的,它確實有助於組織自動執行大任務。
我們在哪裡編寫這些腳本?
我們在文字編輯器中編寫這些腳本。在我們的範例中,我們將使用 Linux 發行版中附帶的 VIM 編輯器。
外殼看起來是這樣的:
在這裡,我們將了解最常用的 bash 指令。
了解您目前所處的路徑非常重要,當我們處理多個專案時,這會變得令人困惑。為了取得目前目錄,我們使用指令pwd
,意思是“列印工作目錄”
pwd
現在我們知道了目前的目錄,讓我們建立一個新資料夾(也可以稱之為目錄)來保存我們的檔案。為此,我們使用mkdir
指令,意思是「建立目錄」。
mkdir <specify your folder name>
建立目錄後,您可以使用ls
指令查看其中的內容。
ls
或者
您也可以使用ls -ltr
命令,該命令以長格式(-l)列出內容,按修改時間(-t)排序,並首先顯示最舊的條目(-r)。
ls -ltr
現在,要移動到資料夾/目錄內,您可以輸入命令cd
,它代表更改目錄,使用 cd 您可以進入資料夾內部,再次輸入 ls 將顯示該資料夾內的所有檔案。
cd <folder_name>
為了退出您目前所在的目錄,您可以使用命令cd ..
,這可以讓您退出該目錄。
cd ..
為了刪除檔案或整個目錄,我們使用命令rm -r
rm -r <name of file or folder>
我們可以使用指令mv
重命名檔。
mv <your-file-name> <new-file-name>
現在讓我們建立一個文件,要建立文件,我們使用touch
指令。
touch <filename>
要列印文件裡的內容,我們使用cat
指令。
cat <filename>
該文件最初是空的,因為我們沒有在文件中加入任何內容。讓我們在文件中加入一些內容。我們將使用 vim 編輯器(文章前面有完整的詳細資訊)來編輯該文件,保存它,然後使用 cat 命令。
Vim 編輯器
該文件現在顯示的是我們寫入的內容。
最後,如果我們想在 shell 上列印一些內容,我們使用命令echo
。
好的,太棒了!我們已經學習了在 shell 中移動的基本命令。現在我們可以討論更有趣的事情了。其實不難,所以不用擔心!
現在,如果您以前從未編寫過腳本,您可能不熟悉 vim 及其相關的所有迷因。嗯,vim 是用於在終端上編寫 bash 腳本的編輯器,還有許多其他編輯器,如 neovim、nano,可以幫助您編寫腳本,但在本教程中我們將使用 vim。
注意:對於初學者來說,您可能會難以使用 vim,不用擔心,這是很正常的。
讓我們來寫第一個 bash 腳本
"#" symbol is used to show the content is a comment not a part of program.
# Type the below command on the shell.
vim bashscriptfile.sh
耶!
注意:您現在無法在編輯器中鍵入或插入任何內容,因為它不會預設在
Insert
模式下開啟。
要啟用Insert
模式,您需要按下鍵盤上的i
鍵,現在您可以像在普通編輯器上一樣書寫。
您可以看到編輯器現在處於插入模式。
棘手的部分
現在您已經在 vim 上完成了寫作,您需要保存它並退出編輯器,為了保存您的進度,我們首先需要按esc
鍵退出插入模式,現在我們輸入:w
命令,這將保存我們的進度,為了在保存進度後退出 vim,我們使用:q
命令。
我們可以使用:wq!
命令直接儲存並退出編輯器。
或者
您也可以使用指令:x
來實現相同的效果。
您可以簡單地編寫命令 bash 或 sh(我們很快就會討論它們)後跟檔案名稱來執行您的範例腳本。
現在您可能已經注意到,我已將檔案副檔名變更為.sh
,檔案名稱中的.sh
副檔名(如bashscriptfile.sh)表示該檔案是一個 shell 腳本,其中包含由 Unix shell 執行的一系列命令。
現在,讓我們來寫一個更好的 shell 腳本。在上面的檔案中,我們沒有在 vim 編輯器中使用#!/bin/bash
,這是因為它是一個非常普通的腳本,只是列印我們提供的命令,但實際上我們處理的是包含大量需要編譯/解釋的程式碼的複雜腳本。
Shell 腳本開頭的 shebang 行#!/bin/bash
告訴作業系統應該使用哪個解釋器(在本例中為位於 /bin/bash 的 Bash shell)來執行腳本,以確保無論使用者的預設 shell 是什麼,腳本都能正確、一致地執行。
#!
:這兩個字元表示該檔案是一個腳本,後面跟著的是解釋器的路徑。
/bin/bash
:這是 Bash shell 解釋器的路徑。
現在,讓我們編寫一個 shell 腳本來自動執行檔案和資料夾的建立過程,該腳本在執行時將建立一個資料夾及其內的 5 個檔案。
vim firstscript.sh
#!/bin/bash
# this is used to ask the name of folder/directory u wanted to create.
read -p "Enter the directory name: " dir_name
# if the folder/directory already exist, show error
if [ -d "$dir_name" ]; then
echo "Error: Directory '$dir_name' already exists."
exit 1
fi
# Creating the directory
mkdir "$dir_name"
# if we are able to create it or not
if [ ! -d "$dir_name" ]; then
echo "Error: Failed to create directory '$dir_name'."
exit 1
fi
# Creating 5 files inside the directory we made.
for i in {1..5}; do
file_name="$dir_name/file_$i.txt"
touch "$file_name"
if [ ! -f "$file_name" ]; then
echo "Error: Failed to create file '$file_name'."
fi
done
echo "Directory '$dir_name' and 5 files created successfully."
exit 0
編寫腳本後保存它,返回終端並執行以下命令,讓我們看看我們是否真的自動建立檔案。
bash firstscript.sh
然後它會要求您輸入資料夾名稱,我輸入了“firstdirectory” 。
🎉🎉 哇!
在執行 shell 腳本時,當您鍵入./ <sample.sh>
命令來執行檔案時,您將看到權限錯誤,這是因為您沒有執行該檔案的權限。
Shell 腳本中的檔案權限對於管理類別 Unix 系統中的存取控制至關重要。 chmod
指令用於改變這些權限,決定誰可以讀取、寫入和執行檔。
chmod
指令根據 4-2-1 規則使用數字程式碼來設定權限。每個數字分別代表所有者、群組和其他人的權限。
4:代表讀取權限。
2:代表寫入權限。
1:代表執行權限。
4+2+1 = 7,這意味著給予每個人文件的完全存取權限(不建議)。
chmod 777 demo.txt
或者
chmod +x demo.txt
在上面的命令中,您授予了文件的完全存取權限,任何人都可以讀寫和執行此文件。
您可以在此處了解有關chmod
命令的更多資訊。
上面我們討論了用來執行 shell 腳本的指令。我們可以同時使用 sh 和 bash。 sh
注重優先可移植性並遵守 POSIX 標準,以實現與類 Unix 系統的最大相容性。 bash
是 Linux 和 macOS 上常見的功能更豐富的 shell,提供命令列編輯和儲存命令歷史記錄的陣列等便利,但犧牲了一些可移植性。
我們可以說 bash 就是 sh,但具有一些更高級的功能。
Shell 腳本中的網路涉及使用 Shell 腳本中的命令列工具與網路互動、傳輸資料和管理網路配置。它允許自動化與網路相關的任務,例如檢查網路連接、下載檔案、設定網路介面、連接到遠端實例等。
Shell 腳本能夠自動執行任務、管理設定和處理檔案操作,這對於系統管理、DevOps 和開發領域的專業人員來說非常有價值。
常用命令
curl
:使用網路協定向伺服器傳輸資料或從伺服器傳輸資料。
以下命令將把 Dev Community 主頁的 HTML 程式碼輸出到您的終端。
curl https://dev.to
ping
:檢查系統與另一台主機的連線。
ping www.google.com
ssh
:安全地連接到遠端主機。該命令用於連接像 Ec2 這樣的遠端實例。
ssh username@ip-address
它們是正常的 if/else 語句,就像任何其他語言一樣。它區別於事實,我們在最後使用fi
來表示結尾。
if [[ condition1 ]]
then
commands1
elif [[ condition2 ]]
then
commands2
else
commands3
fi
讓我們建立一個非常簡單的腳本。
vim condition.sh
正確儲存腳本
位置參數:在 shell 腳本中,我們有位置參數的概念,它儲存傳遞給 shell 腳本的命令列參數。它們被稱為 $1、$2、$3 等等,其中 $1 是第一個參數,$2 是第二個參數,等等。 $0 保留用於腳本檔名。
您可以在 bash 命令和檔案名稱後輸入參數
Shell 腳本中主要有三種類型的迴圈:for、while 和 Until。 for 迴圈遍歷一系列專案,while 迴圈只要條件為真就會執行,until 迴圈只要條件為假就會執行。
for i in {INITIAL_VALUE..TERMINATING_VALUE}
do
# Code
done
vim forloop.sh
現在儲存文件
函數,眾所周知,是可以在整個腳本中呼叫和重複使用的程式碼區塊。
function_name() {
# Commands
}
vim functions.sh
該腳本定義了一個名為 follow 的函數,它接受一個參數並列印語句。
讓我們使用函數和循環來編寫一個腳本。
vim sumScript.sh
注意:如果您忘記如何在 vim 中輸入,請記得按
i
來啟用插入模式。
#!/bin/bash
# Calculate the sum of numbers from 1 to n.
sum_numbers() {
local n=$1
local sum=0
local i=1
while [[ $i -le $n ]]; do
sum=$((sum + i))
i=$((i + 1))
done
echo "Sum of numbers from 1 to $n is: $sum"
}
while true
do
read -p "Enter a positive integer or press q to exit:" input
if [[ "$input" == "q" ]]; then
break
fi
# Check if input is a number
if ! [[ "$input" =~ ^[0-9]+$ ]]; then
echo "Invalid"
continue
fi
sum_numbers "$input"
done
echo "Script completed."
儲存腳本
管道 | & 重定向 (>>)
管道,以|為代表符號,是 shell 腳本中的一個強大功能,允許你將命令連結在一起。管道符號後的命令始終依賴該符號前的命令。
echo 'Hello, Bash piping!' | wc -w
wc -w
命令計算其輸入中的單字數,結果輸出“3”,這清楚地表明了它是如何依賴輸入的。
Grep 指令
grep 指令是 Linux 中的一個強大工具,用於在檔案中搜尋文字或模式。為了搜尋關鍵字、流程或任何特定於組織的內容,grep 命令非常有用。
grep "keyword" <filename>
以下是我在上面建立的文件中搜尋單字demo 的方法。
現在,讓我示範如何使用grep
指令來尋找系統上正在執行的進程。 Grep 在工業界中非常有用,它可以在大型日誌檔案中辨識感興趣的關鍵字,就像我們搜尋特定的流程一樣。
ps -ef | grep "postgres"
Sed 指令
sed
命令,也稱為“流編輯器”,是類 Unix 作業系統中用於文字處理的命令列實用程式。
您可以對文件或輸入流中的文字執行搜尋、取代、插入和刪除操作,而無需在文字編輯器中開啟文件。
讓我們執行一個 bash 腳本來替換文件中的文字。讓我們建立一個touch sedfile.txt
並在其中寫入“這是一個 bash 腳本教程”,然後:
vim sedsamplefile.sh
它將開啟 vim 編輯器,啟用插入模式。
現在讓我們執行腳本。
注意:我已經使用vim編輯器將內容寫入sedfile.txt中。現在我們將執行腳本。
您可以看到腳本按預期工作並且 bash 被 shell 取代。
sed可用於轉換資料格式、清理雜亂資料、自動執行 shell 腳本中重複的文字編輯任務、跨多個文件查找和替換操作以及生成程式碼片段。
Awk 指令
shell腳本中的awk
指令是一個強大的文字處理工具,用於模式掃描和處理。它可以過濾和處理文字資料,使其可用於報告、計算和文字轉換。 AWK 逐行處理文件,將每行分成多個欄位。
vim awk_script.sh
讓我們新增一個腳本來僅顯示已登入使用者的使用者名稱。
儲存檔案
您可以清楚地看到它列印了今天登入的用戶的姓名。
# The $2 indicates the column 2 which was assigned to username and similarly $1 was assigned to date.
awk '{print "User: " $2 " logged in on " $1}'
AWK 通常用於日誌處理、資料擷取和文字轉換。例如,如果我們有一個日誌文件,其中包含日期、用戶名和執行的操作等列,如上所示,我們可以使用 AWK 僅提取相關訊息,如上面的用戶名。
I/O 重新導向:重新導向可讓您變更指令的輸入和輸出流。預設情況下,命令從鍵盤接收輸入並將輸出發送到終端螢幕,但重定向允許您更改輸入的來源或輸出的去向。
將輸出重定向到檔案 (>)
之前我們使用 vim 編輯器來編輯 sedfile.txt,但只能使用終端並使用重定向運算子來完成。
echo "Hello, World!" > sample.txt
這將插入文字“Hello, world!”在 sample.txt 檔案中。
將輸出附加到文件 (>>)
echo "This is an appended line." >> sample.txt
這將在“Hello, world!”下面附加一行。文字.
輸入重定向(< 指令)
cat < output.txt
重定向輸出和錯誤(&> 和 2>)
ls random_file 2> error_log.txt
輸出將是 ls: 無法存取‘random_file’:沒有此檔案或目錄
重定向輸出和錯誤(&> 指令)
ls valid_file Invalid_file &> output.txt
預期輸出:
valid_file
ls: cannot access 'Invalid_file': No such file or directory
之前我們使用 vim 編輯器來編輯 sedfile.txt,但只能使用終端並使用重定向運算子來完成。
I/O 重定向是 Linux 的一個基本概念,它允許使用者有效地管理資料。
錯誤處理對於建立可靠的 shell 腳本來說始終至關重要。它涉及管理程式執行期間的意外情況並確保腳本的行為可預測。
基本錯誤處理
# This option causes the script to exit immediately if a command fails.
set -e
讓我們編寫一個範例腳本。
vim sample.sh
加入一個可以列印文件內容的腳本,但在這裡我們將學習set -e
在出現錯誤時如何派上用場。
在上面的腳本中,我嘗試查看一個不存在的文件,並且set -e
將立即執行,並且腳本中斷。
實際用例:假設任何 AWS CLI 指令(例如,aws ec2 run-instances、aws ec2 authorize-security-group-ingress)失敗,腳本將立即退出。這可以防止腳本在可能損壞的狀態下繼續提供資源。
Trap :Bash 中的 trap 指令是內建函數,可讓您在腳本收到特定訊號時執行特定操作。
信號:信號是發送給進程以通知其事件的軟體中斷。
我相信我們都知道安排任務意味著什麼。在 shell 腳本中,可以使用crontab之類的工具來完成,它是類 Unix 作業系統中的實用程序,可讓您安排作業以特定時間間隔自動執行。這些計劃的作業被稱為「cron 作業」。
實際用例包括 Ec2 實例管理、按計劃時間與資料庫同步資料等。
要深入了解任務調度和 Crontab,您可以在此處探索。
前台作業直接在終端機中運作並阻止進一步輸入直到完成;後台作業透過在命令後面附加「&」來啟用,從而釋放終端。
這些工作對於提高效率至關重要,尤其是在軟體開發中,編譯程式碼、執行測試和部署應用程式可能非常耗時。
透過在背景執行模型訓練或資料庫備份等耗時較長的任務,同時其他監控任務在前台執行,使用者可以繼續工作,從而最大限度地提高生產力和資源利用率。
是時候透過腳本來理解這一點了。
vim sample.sh
複製以下腳本
#!/bin/bash
# Foreground task
echo "Starting a foreground task..."
sleep 3 # Wait for 3 seconds
echo "Foreground task completed."
# Background task
echo "Starting a background task..."
sleep 5 & # Run the sleep command in the background
echo "Background task started!"
echo "Doing other things while background task runs..."
sleep 1
echo "Script is still running."
#The other process runs while this message is being displayed.
sleep 2
echo "All done."
該腳本演示了前台和後台作業的使用。
您可以看到“正在啟動前台任務...”,然後必須等待 3 秒鐘才能發生其他任何事情。這表示前台任務會阻止進一步的輸入直到完成為止。
您可以看到“正在啟動後台任務…”和“後台任務已啟動!”幾乎立即,在後台任務的 sleep 5 命令完成之前。這是因為 & 將 sleep 5 指令放在背景。
啟動後台任務後,腳本立即繼續列印“在後台任務執行時執行其他操作...”,然後暫停另一次睡眠 1。
最後的「全部完成」。即使後台任務(睡眠 5)可能仍在執行,也會出現訊息。該腳本沒有明確等待後台任務完成後再退出。
保持腳本簡單:確保每個腳本都有單一職責,以實現簡單為目標。
使用版本控制:將您的腳本儲存在版本控制系統(如 Git)中以追蹤變更並與他人合作。
檢查工作目錄:驗證腳本是否在正確的目錄中執行。
日誌記錄和故障排除:實作日誌記錄機制來擷取腳本執行細節和錯誤。
文件和幫助選項:使用註釋在腳本中包含文件,並提供幫助選項(例如 -h 或 --help)來指導使用者如何有效地使用腳本。
在函數中使用局部變數:定義函數時,使用局部變數來限制其範圍並避免與全域變數發生意外的交互作用。
基礎架構自動化:AWS 依賴 shell 腳本來自動化許多基礎架構管理任務。例如,shell 腳本可以自動建立新伺服器、設定資源和管理更新,確保其龐大基礎架構的一致可靠運作。
例行檢查:Google 使用 shell 腳本自動執行常規系統管理任務,例如使用者帳戶管理、日誌檔案維護和監控系統資源。這種自動化有助於維持系統健康和穩定
設定管理:Shell 腳本確保應用程式的所有設定都是正確且一致的。他們可以設定資料庫配置,管理應用程式與其他服務的互動方式,以及處理日誌管理。
部署應用程式:可以使用 Shell 腳本來自動化應用程式部署,透過打包應用程式、將其複製到伺服器並將其配置為在所需環境中執行。
是的,它終於結束了,我們探索了 shell 腳本的深度和廣度,我們看到了它如何在各種規模的組織(包括 AWS 和 Google 這樣的巨頭)中為 DevOps、系統管理、資料處理等方面的關鍵任務提供支援。透過自動執行日常任務、管理配置、監控系統和促進部署,shell 腳本仍然是不可或缺的工具。
恭喜🎉🎉,如果你真的堅持到了最後,非常感謝。
如果您喜歡整個教程,請考慮與真正需要的人分享,並關注我以獲取更多此類內容。
對於付費合作,請發送電子郵件至: [email protected]
歡迎透過Twitter 、 LinkedIn 、 Youtube 、 Github與我聯絡。
再次感謝您!
原文出處:https://dev.to/harshit_rwt/master-shell-scripting-zero-to-interview-ready-379e