歷史上,shell 一直是類 Unix 系統(tǒng)的本地命令行解釋器。它已被證明是 Unix 的主要功能之一,并發(fā)展成為一個全新的主題。Linux 提供了各種功能強(qiáng)大的 shell,包括 Bash、Zsh、Tcsh 和 Ksh。這些外殼最令人驚訝的特性之一是其可編程性。創(chuàng)建簡單而有效的 Linux shell 腳本來處理日常工作非常容易。
程序員經(jīng)常通過學(xué)習(xí) hello world 程序來學(xué)習(xí)新語言。這是一個簡單的程序,將字符串 “HelloWorld” 打印到標(biāo)準(zhǔn)輸出中。然后,使用 vim 或 nano 等編輯器創(chuàng)建 hello-world.sh 文件,并將以下行復(fù)制到其中。
echo 命令用于在 bash 中打印信息。它類似于 C 函數(shù) “printf”,并提供了許多常見選項(xiàng),包括轉(zhuǎn)義序列和重定向。將以下行復(fù)制到名為 echo.sh 的文件中,并使其可執(zhí)行,如上所述。
注釋對文檔很有用,是高質(zhì)量代碼庫的要求。將注釋放在處理關(guān)鍵邏輯的代碼中是一種常見的做法。要注釋掉一行,只需在其前面使用 #(hash)字符。例如,請查看下面的 bash 腳本示例。
此腳本將輸出數(shù)字 60。首先,在某些行之前使用 #檢查注釋的使用方式。不過,第一行是一個例外。它被稱為 shebang,讓系統(tǒng)知道在運(yùn)行這個腳本時要使用哪個解釋器。
the square of 5.
如果通過輸入提供的數(shù)字大于 10,上述程序?qū)H顯示輸出。-gt 表示大于;類似地 - lt 表示小于 - le 表示小于等于;且 - ge 表示大于等于。此外,還需要 [[]]。
AND 運(yùn)算符允許我們的程序檢查是否同時滿足多個條件。由 AND 運(yùn)算符分隔的所有部分必須為 true。否則,包含 AND 的語句將返回 false。查看下面的 bash 腳本示例,以更好地了解 AND 的工作原理。
OR 運(yùn)算符是另一個關(guān)鍵的構(gòu)造,它允許我們在腳本中實(shí)現(xiàn)復(fù)雜、健壯的編程邏輯。與 AND 相反,當(dāng) OR 運(yùn)算符的任一操作數(shù)為真時,由 OR 運(yùn)算符組成的語句返回真。僅當(dāng)由 OR 分隔的每個操作數(shù)為假時,它才返回假。
這個簡單的示例演示了 OR 運(yùn)算符如何在 Linuxshell 腳本中工作。只有當(dāng)用戶輸入數(shù)字 15 或 45 時,它才會宣布用戶為獲勝者。|| 符號表示 OR 運(yùn)算符。
上面的程序是不言自明的,所以我們不會逐行剖析它。相反,更改腳本中的變量名稱和值等部分,以檢查它們?nèi)绾我黄鸸ぷ鳌?/div>
13.case 條件
. switch 構(gòu)造是 Linux bash 腳本提供的另一個強(qiáng)大功能。它可以用于需要嵌套條件的地方,但不希望使用復(fù)雜的 if-else elif 鏈。看看下一個例子。
#!/bin/bash
echo -n "Enter a number: "
read num
case $num in
100)
echo "Hundred!!" ;;
200)
echo "Double Hundred!!" ;;
*)
echo "Neither 100 nor 200" ;;
esac
條件寫在 case 和 esac 關(guān)鍵字之間。*)用于匹配除 100 和 200 以外的所有輸入。
14.命令行參數(shù)
在許多情況下,直接從命令 shell 獲取參數(shù)是有益的。下面的示例演示了如何在 bash 中執(zhí)行此操作。
#!/bin/bash
echo "Total arguments : $#"
echo "First Argument = $1"
echo "Second Argument = $2"
運(yùn)行此腳本時,在其名稱后添加兩個附加參數(shù)。我將其命名為 test.sh,調(diào)用過程概述如下。
$ ./test.sh Hey Howdy
因此,1、用于訪問第一個參數(shù);2、用于訪問第二個參數(shù),依此類推。最后,3、用于獲取參數(shù)總數(shù)。
15.使用名稱獲取參數(shù)
下面的示例顯示了如何獲取帶有名稱的命令行參數(shù)。
#!/bin/bash
for arg in "$@"
do
index=$(echo $arg | cut -f1 -d=)
val=$(echo $arg | cut -f2 -d=)
case $index in
X) x=$val;;
Y) y=$val;;
*)
esac
done
((result=x+y))
echo "X+Y=$result"
將此腳本命名為 test.sh,并按如下所示調(diào)用它。
$ ./test.sh X=44 Y=100
它應(yīng)該返回 X+Y=144。這里的參數(shù)存儲在 “$@” 中,腳本使用 Linuxcut 命令獲取它們。
16.連接字符串
字符串處理對于廣泛的現(xiàn)代 bash 腳本來說非常重要。值得慶幸的是,它在 bash 中更加舒適,并允許以更精確、簡潔的方式實(shí)現(xiàn)這一點(diǎn)。請參見下面的示例,了解 bash 字符串連接。
#!/bin/bash
string1="Ubuntu"
string2="Pit"
string=$string1$string2
echo "$string is a great resource for Linux beginners."
17.字符串截取
與許多編程語言不同,bash 不提供任何用于剪切字符串部分的內(nèi)置函數(shù)。然而,下面的示例演示了如何使用參數(shù)展開來實(shí)現(xiàn)這一點(diǎn)。
#!/bin/bash
Str="Learn Bash Commands from UbuntuPit"
subStr=${Str:0:20}
echo $subStr
該腳本應(yīng)打印出 “學(xué)習(xí) Bash 命令” 作為其輸出。參數(shù)展開形式為 ${VAR_NAME:S:L}。這里,S 表示起始位置,L 表示長度。
18.使用 cut 做截取
可以在腳本中使用 Linux cut 命令來截取字符串的一部分,也就是子字符串。下一個示例顯示了如何做到這一點(diǎn)。
#!/bin/bash
Str="Learn Bash Commands from UbuntuPit"
#subStr=${Str:0:20}
subStr=$(echo $Str| cut -d ' ' -f 1-3)
echo $subStr
19.添加兩個值
在 Linux shell 腳本中執(zhí)行算術(shù)運(yùn)算非常容易。下面的示例演示了如何從用戶接收兩個數(shù)字作為輸入并將它們相加。
#!/bin/bash
echo -n "Enter first number:"
read x
echo -n "Enter second number:"
read y
(( sum=x+y ))
echo "The result of addition=$sum"
如您所見,在 bash 中添加數(shù)字相當(dāng)簡單。
20.添加多個值
您可以使用循環(huán)獲取多個用戶輸入并將其添加到腳本中。以下示例顯示了這一點(diǎn)。
#!/bin/bash
sum=0
for (( counter=1; counter<5; counter++ ))
do
echo -n "Enter Your Number:"
read n
(( sum+=n ))
#echo -n "$counter "
done
printf "\n"
echo "Result is: $sum"
但是,省略 (()) 將導(dǎo)致字符串串聯(lián)而不是相加。所以,在你的程序中檢查類似的情況。
21.Bash 中的函數(shù)
與任何編程方言一樣,函數(shù)在 Linux shell 腳本中扮演著重要角色。它們允許管理員創(chuàng)建自定義代碼塊以供頻繁使用。下面的演示將概述函數(shù)如何在 Linux bash 腳本中工作。
#!/bin/bash
function Add()
{
echo -n "Enter a Number: "
read x
echo -n "Enter another Number: "
read y
echo "Adiition is: $(( x+y ))"
}
Add
這里我們像以前一樣添加了兩個數(shù)字。但在這里,我們使用了一個名為 Add 的函數(shù)來完成這項(xiàng)工作。因此,每當(dāng)您需要再次添加時,只需調(diào)用此函數(shù),而不必再次編寫該部分。
22.具有返回值的函數(shù)
最神奇的功能之一是允許數(shù)據(jù)從一個函數(shù)傳遞到另一個函數(shù)。它在各種場景中都很有用。查看下一個示例。
#!/bin/bash
function Greet() {
str="Hello $name, what brings you to UbuntuPit.com?"
echo $str
}
echo "-> what's your name?"
read name
val=$(Greet)
echo -e "-> $val"
這里,輸出包含從 Greet()函數(shù)接收的數(shù)據(jù)。
23.從 Bash 腳本創(chuàng)建目錄
使用 shell 腳本運(yùn)行系統(tǒng)命令的能力使開發(fā)人員的工作效率大大提高。下面的簡單示例將向您展示如何在 shell 腳本中創(chuàng)建目錄。
#!/bin/bash
echo -n "Enter directory name ->"
read newdir
cmd="mkdir $newdir"
eval $cmd
該腳本只需調(diào)用標(biāo)準(zhǔn) shell 命令 mkdir,并在仔細(xì)查看時將目錄名傳遞給它。這個程序應(yīng)該在文件系統(tǒng)中創(chuàng)建一個目錄。您還可以傳遞命令以在 backticks(“)內(nèi)部執(zhí)行,如下所示。
`mkdir $newdir`
24.確認(rèn)存在后創(chuàng)建目錄
如果當(dāng)前工作目錄中已包含同名文件夾,則上述程序?qū)o法運(yùn)行。例如,下面的程序?qū)z查是否存在名為 $dir 的文件夾,如果找不到,則只創(chuàng)建一個。
#!/bin/bash
echo -n "Enter directory name ->"
read dir
if [ -d "$dir" ]
then
echo "Directory exists"
else
`mkdir $dir`
echo "Directory created"
fi
使用 eval 編寫此程序以提高 bash 腳本編寫技能。
25.讀取文件
Bash 腳本允許用戶非常有效地讀取文件。下面的示例將展示如何使用 shell 腳本讀取文件。首先,創(chuàng)建一個名為 editors.txt 的文件,其中包含以下內(nèi)容。
1. Vim
2. Emacs
3. ed
4. nano
5. Code
此腳本將輸出上述 5 行中的每一行。
#!/bin/bash
file='editors.txt'
while read line; do
echo $line
done < $file
26.刪除文件
以下程序?qū)⒀菔救绾卧?Linux shell 腳本中刪除文件。程序?qū)⑹紫纫笥脩籼峁┪募鳛檩斎耄绻募嬖?,則將其刪除。Linux rm 命令在此處執(zhí)行刪除操作。
#!/bin/bash
echo -n "Enter filename ->"
read name
rm -i $name
讓我們輸入 editors.txt 作為文件名,并在要求確認(rèn)時按 y。它應(yīng)該刪除該文件。
27.附加到文件
下面的 shell 腳本示例將向您展示如何使用 bash 腳本將數(shù)據(jù)附加到文件系統(tǒng)上的文件。它向早期的 editors.txt 文件添加了一行。
#!/bin/bash
echo "Before appending the file"
cat editors.txt
echo "6. NotePad++" >> editors.txt
echo "After appending the file"
cat editors.txt
現(xiàn)在您應(yīng)該注意到,我們直接從 Linux bash 腳本使用日常終端命令。
28.測試文件存在
下一個 shell 腳本示例顯示如何檢查 bash 程序中文件的存在。
#!/bin/bash
filename=$1
if [ -f "$filename" ]; then
echo "File exists"
else
echo "File does not exist"
fi
我們直接從命令行傳遞文件名作為參數(shù)。
29.從 Shell 腳本發(fā)送郵件
從 bash 腳本發(fā)送電子郵件非常簡單。下面的簡單示例將演示一種從 bash 應(yīng)用程序執(zhí)行此操作的方法。
#!/bin/bash
recipient=”admin@example.com”
subject=”Greetings”
message=”Welcome to UbuntuPit”
`mail -s $subject $recipient <<< $message`
它將向收件人發(fā)送包含給定主題和消息的電子郵件。
30.解析日期和時間
下一個 bash 腳本示例將向您展示如何使用腳本處理日期和時間。同樣,Linuxdate 命令用于獲取必要的信息,我們的程序執(zhí)行解析。
#!/bin/bash
year=`date +%Y`
month=`date +%m`
day=`date +%d`
hour=`date +%H`
minute=`date +%M`
second=`date +%S`
echo `date`
echo "Current Date is: $day-$month-$year"
echo "Current Time is: $hour:$minute:$second"
運(yùn)行此程序以了解其工作原理。此外,嘗試從終端運(yùn)行 date 命令。
31.sleep 命令
sleep 命令允許 shell 腳本在指令之間暫停。它在許多場景中都很有用,例如執(zhí)行系統(tǒng)級作業(yè)。下一個示例顯示了 shell 腳本中的 sleep 命令。
#!/bin/bash
echo "How long to wait?"
read time
sleep $time
echo "Waited for $time seconds!"
該程序暫停最后一條指令的執(zhí)行,直到 $time 秒,在本例中,用戶提供了這一點(diǎn)。
32.wait 命令
wait 命令用于暫停 Linux bash 腳本中的系統(tǒng)進(jìn)程。查看下面的示例,詳細(xì)了解這在 bash 中的工作方式。
#!/bin/bash
echo "Testing wait command"
sleep 5 &
pid=$!
kill $pid
wait $pid
echo $pid was terminated.
33.顯示上次更新的文件
有時,您可能需要為某些操作查找最后更新的文件。下面的簡單程序向我們展示了如何在 bash 中使用 awk 命令執(zhí)行此操作。它將列出當(dāng)前工作目錄中最近更新或創(chuàng)建的文件。 #!/bin/bash
ls -lrt | grep ^- | awk 'END{print $NF}'
為了簡單起見,我們將避免在本示例中描述 awk 的功能。相反,您可以簡單地復(fù)制此代碼來完成任務(wù)。
34.添加批處理擴(kuò)展
下面的示例將對目錄中的所有文件應(yīng)用自定義擴(kuò)展名。創(chuàng)建一個新目錄,并將一些文件放在其中以供演示。我的文件夾共有五個文件,每個文件名為 test,后跟(0-4)。我已將此腳本編程為在文件末尾添加(.UP)。您可以添加所需的任何擴(kuò)展名。
#!/bin/bash
dir=$1
for file in `ls $1/*`
do
mv $file $file.UP
done
首先,不要從任何常規(guī)目錄嘗試此腳本;相反,請從測試目錄運(yùn)行此命令。此外,您需要提供文件的目錄名作為命令行參數(shù)。對當(dāng)前工作目錄使用句點(diǎn)(.)。
35.打印文件或目錄的數(shù)量
下面的 Linuxbash 腳本查找給定目錄中存在的文件或文件夾的數(shù)量。它使用 Linux find 命令來執(zhí)行此操作。首先,需要傳遞目錄名以從命令行搜索文件。
#!/bin/bash
if [ -d "$@" ]; then
echo "Files found: $(find "$@" -type f | wc -l)"
echo "Folders found: $(find "$@" -type d | wc -l)"
else
echo "[ERROR] Please retry with another folder."
exit 1
fi
如果指定的目錄不可用或存在權(quán)限問題,程序?qū)⒁笥脩糁卦嚒?/div>
36.清理日志文件
下一個簡單的示例演示了在現(xiàn)實(shí)生活中使用 shell 腳本的簡便方法。該程序只需刪除 / var/log 目錄中的所有日志文件。您可以更改保存此目錄的變量以清理其他日志。
#!/bin/bash
LOG_DIR=/var/log
cd $LOG_DIR
cat /dev/null > messages
cat /dev/null > wtmp
echo "Logs cleaned up."
請記住以 root 身份運(yùn)行此 Linuxshell 腳本。
37.使用 Bash 備份腳本
Shell 腳本提供了一種強(qiáng)大的方法來備份文件和目錄。以下示例將備份過去 24 小時內(nèi)修改的每個文件或目錄。該程序使用 find 命令執(zhí)行此操作。
#!/bin/bash
BACKUPFILE=backup-$(date +%m-%d-%Y)
archive=${1:-$BACKUPFILE}
find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"."
exit 0
備份過程成功后,它將打印文件和目錄的名稱。
38.檢查你是否是 root 用戶
下面的示例演示了通過 Linux bash 腳本快速確定用戶是否為 root 用戶的方法。
#!/bin/bash
ROOT_UID=0
if [ "$UID" -eq "$ROOT_UID" ]
then
echo "You are root."
else
echo "You are not root"
fi
exit 0
此腳本的輸出取決于運(yùn)行它的用戶。它將根據(jù) $UID 匹配根用戶。
39.從文件中刪除重復(fù)行
文件處理需要相當(dāng)長的時間,并在許多方面阻礙了管理員的工作效率。例如,在文件中搜索重復(fù)項(xiàng)可能會成為一項(xiàng)艱巨的任務(wù)。幸運(yùn)的是,您可以使用一個簡短的 shell 腳本來完成此操作。
#! /bin/sh
echo -n "Enter Filename-> "
read filename
if [ -f "$filename" ]; then
sort $filename | uniq | tee sorted.txt
else
echo "No $filename in $pwd...try again"
fi
exit 0
上面的腳本逐行遍歷文件并刪除所有重復(fù)的行。然后,它將新內(nèi)容放入新文件,并保持原始文件的完整性。
40.系統(tǒng)維護(hù)
我經(jīng)常使用一個小的 Linuxshell 腳本來升級我的系統(tǒng),而不是手動升級。下面的簡單 shell 腳本將向您展示如何做到這一點(diǎn)。
#!/bin/bash
echo -e "\n$(date "+%d-%m-%Y --- %T") --- Starting work\n"
apt-get update
apt-get -y upgrade
apt-get -y autoremove
apt-get autoclean
echo -e "\n$(date "+%T") \t Script Terminated"
該腳本還處理不再需要的舊包。您需要使用 sudo 運(yùn)行此腳本,否則它將無法正常工作。