linuxshell格式
編寫shell腳本 首先你要有Linux命令的基礎,怎麼進入文件,怎麼執行文件,有什麼命令等等。
我們的shell 類型有很多,常見的shell環境有sh,bash,csh,zsh等等。在Linux的腳本中可以最常見的就是 sh或者shell。在shell腳本中最開始 要指定shell環境。於是乎我們有了shell的沙邦:
/bin/sh 或者/bin/bash
shell腳本的格式:shell腳本一般是以*.sh 為名字,在許可權上面是有可執行許可權x的也就是chmod u+x *.sh
命令的執行:3種:
sh 腳本路徑/腳本名
cd 腳本路徑 && ./腳本名
soure 腳本路徑/腳本
寫一個最簡單的腳本吧:
[root@linuxprobe ~]#vim 1.sh
/bin/sh
echo "this is my frist scripts,more and more linux ,you can read 《Linux就該這樣學》"
[root@linuxprobe ~]#chmod u+x 1.sh
[root@linuxprobe ~]#./1.sh
this is my frist scripts,more and more linux ,you can read 《Linux就該這樣學》
學習Linux需要多學多練
② linux shell 怎麼寫
在進行linux測試時編寫腳本是必不可少的,Shell腳本的名稱可以隨便定義,也不要什麼後綴名,例如可以寫abc,smartzip這類名稱,運行時只要鍵入
./smartzip就能運行腳本了。。
每行命令開頭處不用就空格也行。。
第1部分. Linux 腳本編寫基礎
1.1 語法基本介紹
1.1.1 開頭
程序必須以下面的行開始(必須方在文件的第一行):
#!/bin/sh
符號#!用來告訴系統它後面的參數是用來執行該文件的程序。在這個例子中我們使用/bin/sh來執行程序。
當編輯好腳本時,如果要執行該腳本,還必須使其可執行。
要使腳本可執行:
編譯 chmod +x filename 這樣才能用./filename 來運行
1.1.2 注釋
在進行shell編程時,以#開頭的句子表示注釋,直到這一行的結束。我們真誠地建議您在程序中使用注釋。
如果您使用了注釋,那麼即使相當長的時間內沒有使用該腳本,您也能在很短的時間內明白該腳本的作用及工作原理。
1.1.3 變數
在其他編程語言中您必須使用變數。在shell編程中,所有的變數都由字元串組成,並且您不需要對變數進行聲明。要賦值給一個變數,您可以這樣寫:
#!/bin/sh
#對變數賦值:
a="hello world"
# 現在列印變數a的內容:
echo "A is:"
echo $a
有時候變數名很容易與其他文字混淆,比如:
num=2
echo "this is the $numnd"
這並不會列印出"this is the 2nd",而僅僅列印"this is the ",因為shell會去搜索變數numnd的值,但是這個變數時沒有值的。可以使用花括弧來告訴shell我們要列印的是num變數:
num=2
echo "this is the ${num}nd"
這將列印: this is the 2nd
1.1.4 環境變數
由export關鍵字處理過的變數叫做環境變數。我們不對環境變數進行討論,因為通常情況下僅僅在登錄腳本中使用環境變數。
1.1.5 Shell命令和流程式控制制
在shell腳本中可以使用三類命令:
1)Unix 命令:
雖然在shell腳本中可以使用任意的unix命令,但是還是由一些相對更常用的命令。這些命令通常是用來進行文件和文字操作的。
常用命令語法及功能
echo "some text": 將文字內容列印在屏幕上
ls: 文件列表
wc –l file :計算文件行數
wc -w file:計算文件中的單詞數
wc -c file:計算文件中的字元數
cp sourcefile destfile: 文件拷貝
mv oldname newname : 重命名文件或移動文件
rm file: 刪除文件
grep 'pattern' file: 在文件內搜索字元串比如:grep 'searchstring' file.txt
cut -b colnum file: 指定欲顯示的文件內容範圍,並將它們輸出到標准輸出設備比如:輸出每行第5個到第9個字元cut -b5-9 file.txt千萬不要和cat命令混淆,
這是兩個完全不同的命令
cat file.txt: 輸出文件內容到標准輸出設備(屏幕)上
file somefile: 得到文件類型
read var: 提示用戶輸入,並將輸入賦值給變數
sort file.txt: 對file.txt文件中的行進行排序
uniq: 刪除文本文件中出現的行列比如: sort file.txt | uniq
expr: 進行數學運算Example: add 2 and 3expr 2 "+" 3
find: 搜索文件比如:根據文件名搜索find . -name filename -print
tee: 將數據輸出到標准輸出設備(屏幕) 和文件比如:somecommand | tee outfile
basename file: 返回不包含路徑的文件名比如: basename /bin/tux將返回 tux
dirname file: 返迴文件所在路徑比如:dirname /bin/tux將返回 /bin
head file: 列印文本文件開頭幾行
tail file : 列印文本文件末尾幾行
sed: Sed是一個基本的查找替換程序。可以從標准輸入(比如命令管道)讀入文本,並將
結果輸出到標准輸出(屏幕)。該命令採用正則表達式(見參考)進行搜索。不要和shell中的通配符相混淆。比如:將linuxfocus 替換為LinuxFocus :cat text.file | sed 's/linuxfocus/LinuxFocus/' > newtext.fileawk: awk 用來從文本文件中提取欄位。預設地,欄位分割符是空格,可以使用-F指定其他分割符。
cat file.txt | awk -F, '{print $1 "," $3 }'這里我們使用,作為欄位分割符,同時列印第一個和第三個欄位。如果該文件內容如下: Adam Bor, 34, IndiaKerry Miller, 22, USA命令輸出結果為:Adam Bor, IndiaKerry Miller, USA
2) 概念: 管道, 重定向和backtick
這些不是系統命令,但是他們真的很重要。
管道 (|) 將一個命令的輸出作為另外一個命令的輸入。
grep "hello" file.txt | wc -l
在file.txt中搜索包含有」hello」的行並計算其行數。
在這里grep命令的輸出作為wc命令的輸入。當然您可以使用多個命令。
重定向:將命令的結果輸出到文件,而不是標准輸出(屏幕)。
> 寫入文件並覆蓋舊文件
>> 加到文件的尾部,保留舊文件內容。
反短斜線
使用反短斜線可以將一個命令的輸出作為另外一個命令的一個命令行參數。
命令:
find . -mtime -1 -type f -print
用來查找過去24小時(-mtime –2則表示過去48小時)內修改過的文件。如果您想將所有查找到的文件打一個包,則可以使用以下腳本:
#!/bin/sh
# The ticks are backticks (`) not normal quotes ('):
tar -zcvf lastmod.tar.gz `find . -mtime -1 -type f -print`
3)流程式控制制
1.if
"if" 表達式 如果條件為真則執行then後面的部分:
if ....; then
....
elif ....; then
....
else
....
fi
大多數情況下,可以使用測試命令來對條件進行測試。比如可以比較字元串、判斷文件是否存在及是否可讀等等…
通常用" [ ] "來表示條件測試。注意這里的空格很重要。要確保方括弧的空格。
[ -f "somefile" ] :判斷是否是一個文件
[ -x "/bin/ls" ] :判斷/bin/ls是否存在並有可執行許可權
[ -n "$var" ] :判斷$var變數是否有值
[ "$a" = "$b" ] :判斷$a和$b是否相等
執行man test可以查看所有測試表達式可以比較和判斷的類型。
直接執行以下腳本:
#!/bin/sh
if [ "$SHELL" = "/bin/bash" ]; then
echo "your login shell is the bash (bourne again shell)"
else
echo "your login shell is not bash but $SHELL"
fi
變數$SHELL包含了登錄shell的名稱,我們和/bin/bash進行了比較。
快捷操作符
熟悉C語言的朋友可能會很喜歡下面的表達式:
[ -f "/etc/shadow" ] && echo "This computer uses shadow passwors"
這里 && 就是一個快捷操作符,如果左邊的表達式為真則執行右邊的語句。
您也可以認為是邏輯運算中的與操作。上例中表示如果/etc/shadow文件存在則列印」 This computer uses shadow passwors」。同樣或操作(||)在shell編程中也是可用的。這里有個例子:
#!/bin/sh
mailfolder=/var/spool/mail/james
[ -r "$mailfolder" ]' '{ echo "Can not read $mailfolder" ; exit 1; }
echo "$mailfolder has mail from:"
grep "^From " $mailfolder
該腳本首先判斷mailfolder是否可讀。如果可讀則列印該文件中的"From" 一行。如果不可讀則或操作生效,列印錯誤信息後腳本退出。這里有個問題,那就是我們必須有兩個命令:
-列印錯誤信息
-退出程序
我們使用花括弧以匿名函數的形式將兩個命令放到一起作為一個命令使用。一般函數將在下文提及。
不用與和或操作符,我們也可以用if表達式作任何事情,但是使用與或操作符會更便利很多。
2.case
case :表達式可以用來匹配一個給定的字元串,而不是數字。
case ... in
...) do something here ;;
esac
讓我們看一個例子。 file命令可以辨別出一個給定文件的文件類型,比如:
file lf.gz
這將返回:
lf.gz: gzip compressed data, deflated, original filename,
last modified: Mon Aug 27 23:09:18 2001, os: Unix
我們利用這一點寫了一個叫做smartzip的腳本,該腳本可以自動解壓bzip2, gzip 和zip 類型的壓縮文件:
#!/bin/sh
ftype=`file "$1"`
case "$ftype" in
"$1: Zip archive"*)
unzip "$1" ;;
"$1: gzip compressed"*)
gunzip "$1" ;;
"$1: bzip2 compressed"*)
bunzip2 "$1" ;;
*) echo "File $1 can not be uncompressed with smartzip";;
esac
您可能注意到我們在這里使用了一個特殊的變數$1。該變數包含了傳遞給該程序的第一個參數值。
也就是說,當我們運行:
smartzip articles.zip
$1 就是字元串 articles.zip
3. selsect
select 表達式是一種bash的擴展應用,尤其擅長於互動式使用。用戶可以從一組不同的值中進行選擇。
select var in ... ; do
break
done
.... now $var can be used ....
下面是一個例子:
#!/bin/sh
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do
break
done
echo "You have selected $var"
下面是該腳本運行的結果:
What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 1
You have selected Linux
4.loop
loop表達式:
while ...; do
....
done
while-loop 將運行直到表達式測試為真。will run while the expression that we test for is true.
關鍵字"break" 用來跳出循環。而關鍵字」continue」用來不執行餘下的部分而直接跳到下一個循環。
for-loop表達式查看一個字元串列表 (字元串用空格分隔) 然後將其賦給一個變數:
for var in ....; do
....
done
在下面的例子中,將分別列印ABC到屏幕上:
#!/bin/sh
for var in A B C ; do
echo "var is $var"
done
下面是一個更為有用的腳本showrpm,其功能是列印一些RPM包的統計信息:
#!/bin/sh
# list a content summary of a number of RPM packages
# USAGE: showrpm rpmfile1 rpmfile2 ...
# EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm
for rpmpackage in $*; do
if [ -r "$rpmpackage" ];then
echo "=============== $rpmpackage =============="
rpm -qi -p $rpmpackage
else
echo "ERROR: cannot read file $rpmpackage"
fi
done
這里出現了第二個特殊的變數$*,該變數包含了所有輸入的命令行參數值。
如果您運行showrpm openssh.rpm w3m.rpm webgrep.rpm
此時 $* 包含了 3 個字元串,即openssh.rpm, w3m.rpm and webgrep.rpm.
5. 引號
在向程序傳遞任何參數之前,程序會擴展通配符和變數。這里所謂擴展的意思是程序會把通配符(比如*)替換成合適的文件名,它變數替換成變數值。為了防止程序作這種替換,您可以使用引號:讓我們來看一個例子,假設在當前目錄下有一些文件,兩個jpg文件, mail.jpg 和tux.jpg。
1.2 編譯SHELL腳本
#ch#!/bin/sh mod +x filename
cho *.jpg ∪緩螅梢醞ü淙耄?./filename 來執行您的腳本。
這將列印出"mail.jpg tux.jpg"的結果。
引號 (單引號和雙引號) 將防止這種通配符擴展:
#!/bin/sh
echo "*.jpg"
echo '*.jpg'
這將列印"*.jpg" 兩次。
單引號更嚴格一些。它可以防止任何變數擴展。雙引號可以防止通配符擴展但允許變數擴展。
#!/bin/sh
echo $SHELL
echo "$SHELL"
echo '$SHELL'
運行結果為:
/bin/bash
/bin/bash
$SHELL
最後,還有一種防止這種擴展的方法,那就是使用轉義字元——反斜桿:
echo /*.jpg
echo /$SHELL
這將輸出:
*.jpg
$SHELL
6. Here documents
當要將幾行文字傳遞給一個命令時,here documents(譯者註:目前還沒有見到過對該詞適合的翻譯)一種不錯的方法。對每個腳本寫一段幫助性的文字是很有用的,此時如果我們四有那個 here documents就不必用echo函數一行行輸出。 一個 "Here document" 以
here document 就是一段特殊目的的代碼塊. 他使用I/O 重定向的形式來將一個命令序列傳遞到一個交互程序或者命令中, 比如ftp, cat, 或者ex文本編輯器.
1 COMMAND
limit string 用來劃定命令序列的范圍(譯者注: 兩個相同的limit string之間就是命令序列). 特殊符號
而here document 的形式看上去是如下的樣子:
1 #!/bin/bash
2 interactive-program
選擇一個名字非常詭異的limit string將會避免命令列表和limit string重名的問題.
下面是一個例子,在該例子中,我們對多個文件進行重命名,並且使用here documents列印幫助:
#!/bin/sh
# we have less than 3 arguments. Print the help text:
if [ $# -lt 3 ] ; then
cat
4)函數
如果您寫了一些稍微復雜一些的程序,您就會發現在程序中可能在幾個地方使用了相同的代碼,並且您也會發現,如果我們使用了函數,會方便很多。一個函數是這個樣子的:
functionname()
{
# inside the body $1 is the first argument given to the function
# $2 the second ...
body
}
您需要在每個程序的開始對函數進行聲明。
下面是一個叫做xtitlebar的腳本,使用這個腳本您可以改變終端窗口的名稱。
這里使用了一個叫做help的函數。正如您可以看到的那樣,這個定義的函數被使用了兩次。
#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{
cat shift by 2
--) shift;break;; # end of options
-*) echo "error: no such option $1. -h for help";exit 1;;
*) break;;
esac
done
echo "opt_f is $opt_f"
echo "opt_l is $opt_l"
echo "first arg is $1"
echo "2nd arg is $2"
您可以這樣運行該腳本:
cmdparser -l hello -f -- -somefile1 somefile2
返回的結果是:
opt_f is 1
opt_l is hello
first arg is -somefile1
2nd arg is somefile2
這個腳本是如何工作的呢?腳本首先在所有輸入命令行參數中進行循環,將輸入參數與case表達式進行比較,如果匹配則設置一個變數並且移除該參數。根據unix系統的慣例,首先輸入的應該是包含減號的參數.
第2部分 實例
現在我們來討論編寫一個腳本的一般步驟。任何優秀的腳本都應該具有幫助和輸入參數。並且寫一個偽腳本(framework.sh),該腳本包含了大多數腳本都需要的框架結構,是一個非常不錯的主意。這時候,在寫一個新的腳本時我們只需要執行一下命令:
cp framework.sh myscript
然後再插入自己的函數。
讓我們再看兩個例子:
(1)二進制到十進制的轉換
腳本 b2d 將二進制數 (比如 1101) 轉換為相應的十進制數。這也是一個用expr命令進行數學運算的例子:
#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{
cat
第3部分:調試
最簡單的調試命令當然是使用echo命令。您可以使用echo在任何懷疑出錯的地方列印任何變數值。這也是絕大多數的shell程序員要花費80%的時間來調試程序的原因。Shell程序的好處在於不需要重新編譯,插入一個echo命令也不需要多少時間。
shell也有一個真實的調試模式。如果在腳本"strangescript" 中有錯誤,您可以這樣來進行調試:
sh -x strangescript
這將執行該腳本並顯示所有變數的值。
shell還有一個不需要執行腳本只是檢查語法的模式。可以這樣使用:
sh -n your_script
這將返回所有語法錯誤
調試shell程序過程
用戶剛編寫完Shell程序中,不可避免的會有錯誤,這時我們可以利用Bsh中提供的跟蹤選項,該選項會顯示剛剛執行的命令及參數。用戶可以通過set命令打開-x選項或在啟動Shell使用-x選項將Shell設置成跟蹤模式。例如有下面代碼ice_tx:
if [ $# -eq 0 ]
then
echo "usage:sumints integer list"
exit 1
fi
sum=0
until [ $# -eq 0 ]
do
sum='expr $sum + $1'
shift
done
echo $sum
我們用跟蹤模式運行:
$sh -x ice_tx 2 3 4
結果顯示:
+[ 3 -eq 0 ]
+sum=0
+[ 3 -eq 0 ]
+expr 0+2
+sum=2
+shift
+[ 2 -eq 0 ]
+expr 2+3
+sum=5
+shift
+[ 1 -eq 0 ]
+expr 5+4
+sum=9
+[ 0 -eq 0 ]
+echo 9
9
從上面可以看出,跟蹤模式下Shell顯示執行的每一條命令以及該命令使用的變數替換後的參數值。一些控制字如if、then、until等沒顯示。
③ 『Linux 干貨』#1 終端與Shell(簡明)
繼 Git 後貴系的另一個暑培項目,講授 Linux 的基本用法,恰好這學期「操作系統」課程實驗需要用到 Linux,而且實驗室的伺服器也需要學習相關用法,故學之。
本文部分內容參考了清華 ZAH 同學的教程,部分參考了 劉遄 老師的《 Linux 就該這么學 》, 菜鳥教程-Linux 。
Linux,全稱 GNU/Linux,是一套免費使用和自由傳播的類 Unix 操作系統。相比於其他系統,Linux 更加穩定且有效率、更加安全、相對不耗資源……以至於幾乎所有 長期穩定運行的網站伺服器 上、在 處理大數據的集群系統 中,以及需要 協同工作的伺服器環境 都採用 Linux 系統。
Linux 嚴格來說是單指操作系統的 內核 ,因操作系統中包含了許多用戶圖形介面和其他實用工具。如今 Linux 常用來指「基於 Linux 的完整操作系統」,內核則改以「Linux 內核」稱之。
一些組織或廠商將 Linux 內核與各種軟體和文檔 包裝 起來,並提供系統安裝界面和系統配置、設定與管理工具,就構成了 Linux 的發行版本。
在學習 Linux 的過程中,有幾個易混淆的概念:
命令行界面(Command-Line Interface,CLI)是在圖形用戶界面得到普及之前使用最為廣泛的用戶界面,它通常不支持滑鼠,用戶通過鍵盤輸入指令,計算機接收到指令後,予以執行。也有人稱之為字元用戶界面(Character User Interface,CUI)。
一般來說,在 伺服器 中較多採用的是 CLI 界面,或許有以下幾點原因:
Shell 是一個用 C 語言編寫的程序,它是用戶使用 Linux 等系統的橋梁,如同「 殼 」一般。它的本質是一個 命令解釋器 ,將用戶輸入的命令(符合 Shell 語法)處理成對應 操作系統的控制命令 ,處理完畢後再將結果反饋給用戶。
不同操作系統下面的 Shell 種類眾多,常見的有:
Ken Thompson 的 sh 是第一種 Unix Shell,本教程關注的是 Bash,也就是 Bourne Again Shell,Bash 也是大多數 Linux 系統默認的 Shell。
終端 (Terminal),是一種用來讓用戶輸入數據至計算機,以及顯示其計算結果的機器。早期的終端通常就是一台 電子打字機 (Teletypewriter, TTY),後來隨著計算機的發展,打字機被鍵盤和顯示器取代,而 GUI 界面也成了主流。
於是,這時候我們就需要一個程序來模擬傳統終端的行為,即 終端模擬器 (Terminal Emulator),當用戶打開終端模擬器時,實際上是進入一個 會話進程 (Session)。終端模擬器有很多,這里舉幾個經典的例子:
在 Linux 系統中打開終端時,會看到一個提示符,通常類似 hewei@hewei-VirtualBox ~$ 。在提示符下,命令會被 Shell 環境 解析並反饋 到終端中。
提示符是 Shell 最主要的 文本介面 。它告訴你,你的主機名是 hewei-VirtualBox ,你現在的身份是 hewei 並且你當前的 工作目錄 (Current working directory)是 ~ (默認在 /home/hewei/ 用戶目錄)。
$ 符號表示您現在的身份不是 root ,輸入如下命令可以暫時切換到 root 許可權:
輸入密碼後,可以看到提示符變成了 root@hewei-VirtualBox:/home/hewei# ,其中 # 符號就是超級用戶許可權的標志。再輸入 exit 即可退回普通用戶身份。
在 Git學習筆記 #1 基礎知識介紹 中,已經簡單介紹了命令行界面的一些使用技巧,這些命令在 Linux 系統的 Bash 中同樣使用。這里羅列出 Linux 常用快捷鍵:
常見的執行 Linux 命令的格式是這樣的: 命令名稱 [命令參數] [命令對象] 。其中,命令參數用於對命令進行調整,使之更好地貼近需求,參數分為 長格式 和 短格式 ,如: man --help , man -h 。短格式之間可以合並,合並後僅保留一個減號即可。
在 Linux 相關的手冊中,我們會約定俗成地將可選擇的、非必需的參數使用 中括弧 引起來,而命令所要求的、必須有的參數或對象值,則不帶中括弧。
此外,要注意 Linux 系統中的命令、參數、對象都是 嚴格區分大小寫 的。
Shell 除了是一個 互動式 (Interactive)的命令解釋器,它還是一種 程序設計語言 (Shell Script)。它定義了各種變數和參數,並提供了許多在高級語言中才具有的控制結構,包括循環和分支。
用 Shell 編寫的 腳本文件 即 .sh 文件,它能在 Shell 環境下運行,fork 出一個 子進程 ,調用系統內核來執行 批處理 (Batch)的系統控制。在文件的第一行,通常是 #!/bin/bash ,這句話約定了這個腳本需要哪種 Shell 環境來執行。
通過如下命令就可以執行一個 Shell 腳本:
下面羅列了部分常用指令與參數的介紹,更多功能請在幫助手冊中檢索。
④ linux中,怎麼通過shell語句獲取當前日期,輸出格式要求20111224.
在Linux下,可以通過date語句來獲取當前日期:
輸入:date +%Y%m%d
輸出:20190314
命令實際執行情況如下圖:
(4)linuxshell格式擴展閱讀
GNU 對 date 命令的另一個擴展是 -d 選項,使用這個功能強大的選項,您可以完成很多有意義的工作。
1、快速地查明一個特定的日期究竟是星期幾:
輸入:date -d "nov 22"
輸出:2019年 11月 22日 星期五 00:00:00 CST
在本示例中,您可以看到今年(2019年)的 11 月 22 日是星期五。
2、獲得相對日期
-d 選項還可以告訴您,相對於當前日期之前或者以後的日期。
如,您需要了解兩星期以後的日期,那麼:
輸入: date -d "2 weeks"
輸出:2019年 03月 29日 星期五 00:12:24 CST
3、使用 next/last指令,您可以得到以後的星期幾是哪一天:
輸入: date -d "next monday" (下周一的日期)
輸入: date -d next-day +%Y%m%d(明天的日期)或者:date -d tomorrow +%Y%m%d
輸入: date -d last-day +%Y%m%d(昨天的日期) 或者:date -d yesterday +%Y%m%d
輸入: date -d last-month +%Y%m(上個月是幾月)
輸入: date -d next-month +%Y%m(下個月是幾月)
4、使用 ago 指令,您可以得到過去的日期:
輸入: date -d "30 days ago" (30天前的日期)
5、您可以使用負數以得到相反的日期:
輸入: date -d "dec 14 -2 weeks" (相對:dec 14這個日期的兩周前的日期)
輸入: date -d "-100 days" (100天以前的日期)
輸入: date -d "50 days" (50天後的日期)
⑤ Linux如何編寫shell腳本
一般以#!/bin/sh開頭(不是必須要寫,但一定要單獨一行),指定執行這個腳本的shell程序(也可以用#!/bin/zsh或其他),然後就是堆命令了。
Linux的shell腳本支持很多功能,加上Linux高度模塊化的命令,完全可以用shell腳本寫出復雜的程序。
以上只是簡單介紹如何開始寫shell腳本,如果要寫復雜的腳本,還需要深入學習相關知識(如if——fi、case——esac等結構)。
當然,還需要給腳本加上可執行許可權(chmod +x ./file.sh),否則可以用sh ./file.sh方式執行腳本(這里的sh是執行腳本所需shell,命令也可以是zsh ./file.sh或其他)。
整個shell腳本,其實就相當於你在終端輸入的一系列命令,如果想在shell里做什麼,就先想想在終端可以做什麼吧,字元的的連接,就是直接用 "" 雙引號,輸出,變數定義無 $ 符號,但是使用時一定要加上 $ 符號。
"=" 賦值符號,兩邊一定不能有空格,這和其他語言有區別,尤其是你還有自己代碼美觀風格時特別注意,否則會報語法錯誤!
for 中的數組內容是以 " " 空格分隔,而非 "," 逗號分格。
條件判斷 [ true ] 中括弧 後面需要有一個空格,但是兩個中括弧之間不能有空格如 [[ true ]]。
while 條件判斷可以用 () 括弧,也可以用 [[ ]] 中括弧。
如果用windows寫shell,一定要注意換行符格式 而非 , 需要藉助一些編輯器(如notepad++)更改換行符格式!
⑥ linux命令和shell命令有什麼區別啊
shell翻譯成殼的意思,它是包裹在Linux內核外層的,一個可通過一系列的Linux命令對操作系統發出相關指令的人機界面。shell可以通過其條件語句和循環語句等,把一系列Linux命令結合在一起,形成一個相當於面向過程的程序,即shell
script,從而實現一些復雜的功能。
shell可以說是Linux命令集的概稱,屬於命令行的人機界面。shell是一個用C語言編寫的程序,它是用戶使用Linux的橋梁。shell既是一個命令語言,也是一個程序設計語言;其次,shell也指一種應用程序,這個應用程序提供了一個界面,用戶通過這個界面訪問操作系統內核的服務。
由此可見,shell相當於經過裝飾的命令行,它與命令行一樣,都能操作Linux;但是shell是面向過程的,相當於有了一定的邏輯和過程,而命令行只是單一的操作。
linux命令是對Linux系統進行管理的命令。對於Linux系統來說,無論是中央處理器、內存、磁碟驅動器、鍵盤、滑鼠,還是用戶等都是文件,Linux系統管理的命令是它正常運行的核心,與之前的DOS命令類似。linux命令在系統中有兩種類型:內置Shell命令和Linux命令。
shell與linux命令的區別
1、直接在命令行執行,就是在當前的shell環境下執行,比如涉及到一些環境變數的時候,必須在當前shell環境里執行。
2、在腳本執行的話,會fork一個子進程,所有操作都在子進程中進行。如果涉及到一些在腳本里設置環境變數的東西,腳本結束了,環境變數就消失了,如果是修改環境變數的話,需要特別注意。
3、shell可以重復或批量地進行一些命令,你也可以把自己要重復執行的命令寫到腳本裡面執行,而命令行的話就需要一個一個的輸入命令,比較麻煩。
⑦ Linux Shell 腳本編程最佳實踐
IT路邊社
前言
與其它的編碼規范一樣,這里所討論的不僅僅是編碼格式美不美觀的問題, 同時也討論一些約定及編碼標准。這份文檔主要側重於我們所普遍遵循的規則,對於那些不是明確強制要求的,我們盡量避免提供意見。
編碼規范對於程序員而言尤為重要,有以下幾個原因:
本文檔中的准則致力於最大限度達到以下原則:
盡管本文檔涵蓋了許多基礎知識,但應注意的是,沒有編碼規范可以為我們回答所有問題,開發人員始終需要再編寫完代碼後,對上述原則做出正確的判斷。
注 :未明確指明的則默認為必須(Mandatory)
主要參考如下文檔:
僅建議Shell用作相對簡單的實用工具或者包裝腳本。因此單個shell腳本內容不宜太過復雜。
在選擇何時使用shell腳本時時應遵循以下原則:
可執行文件不建議有擴展名,庫文件必須使用 .sh 作為擴展名,且應是不可執行的。
執行一個程序時,無需知道其編寫語言,且shell腳本並不要求具有擴展名,所以更傾向可執行文件沒有擴展名。
而庫文件知道其編寫語言十分重要,使用 .sh 作為特定語言後綴的擴展名,可以和其他語言編寫的庫文件加以區分。
文件名要求全部小寫, 可以包含下劃線 _ 或連字元 - , 建議可執行文件使用連字元,庫文件使用下劃線。
正例:
反例:
源文件編碼格式為UTF-8。避免不同操作系統對文件換行處理的方式不同,一律使用 LF 。
每行最多不超過120個字元。每行代碼最大長度限制的根本原因是過長的行會導致閱讀障礙,使得縮進失效。
除了以下兩種情況例外:
如出現長度必須超過120個字元的字元串,應盡量使用here document或者嵌入的換行符等合適的方法使其變短。
示例:
除了在行結束使用換行符,空格是源文件中唯一允許出現的空白字元。
對從來沒有用到的或者被注釋的方法、變數等要堅決從代碼中清理出去,避免過多垃圾造成干擾。
Bash 是唯一被允許使用的可執行腳本shell。
可執行文件必須以 #!/bin/bash 開始。請使用 set 來設置shell的選項,使得用 bash echo "Process $: Done making $$$."
# 示例7:命令參數及路徑不需要引號 grep -li Hugo /dev/ "$1"
# 示例8:常規變數用雙引號,ccs可能為空的特殊情況可不用引號 git send-email --to "${reviewers}" ${ccs:+"--cc" "${ccs}"}
# 示例9:正則用單引號,$1可能為空的特殊情況可不用引號 grep -cP '([Ss]pecial||?characters*) ${1:+"$1"}
# 示例10:位置參數傳遞推薦帶引號的"$@",所有參數作為單字元串傳遞用帶引號的"$*" # content of t.sh func_t { echo num: $# echo args: 1:$1 2:$2 3:$3 }
func_t "$@" func_t "$*" # 當執行 ./t.sh a b c 時輸出如下: num: 3 args: 1:a 2:b 3:c num: 1 args: 1:a b c 2: 3:
使用 $(command) 而不是反引號。
因反引號如果要嵌套則要求用反斜杠轉義內部的反引號。而 $(command) 形式的嵌套無需轉義,且可讀性更高。
正例:
反例:
條件測試
使用 [[ ... ]] ,而不是 [ , test , 和 /usr/bin/[ 。
因為在 [[ 和 ]] 之間不會出現路徑擴展或單詞切分,所以使用 [[ ... ]] 能夠減少犯錯。且 [[ ... ]] 支持正則表達式匹配,而 [ ... ] 不支持。參考以下示例:
盡可能使用變數引用,而非字元串過濾。
Bash可以很好的處理空字元串測試,請使用空/非空字元串測試方法,而不是過濾字元,讓代碼具有更高的可讀性。正例:
反例:
正例:
反例:
正例:
反例:
文件名擴展
當進行文件名的通配符擴展時,請指定明確的路徑。
當目錄中有特殊文件名如以 - 開頭的文件時,使用帶路徑的擴展通配符 ./* 比不帶路徑的 * 要安全很多。
應該避免使用eval。
Eval在用於分配變數時會修改輸入內容,但設置變數的同時並不能檢查這些變數是什麼。反例:
請使用進程替換或者for循環,而不是通過管道連接while循環。
這是因為在管道之後的while循環中,命令是在一個子shell中運行的,因此對變數的修改是不能傳遞給父shell的。
這種管道連接while循環中的隱式子shell使得bug定位非常困難。反例:
如果你確定輸入中不包含空格或者其他特殊符號(通常不是來自用戶輸入),則可以用for循環代替。例如:
使用進程替換可實現重定向輸出,但是請將命令放入顯式子 shell,而非 while 循環創建的隱式子 shell。例如:
總是檢查返回值,且提供有用的返回值。
對於非管道命令,使用 $? 或直接通過 if 語句來檢查以保持其簡潔。
例如:
當內建命令可以完成相同的任務時,在shell內建命令和調用外部命令之間,應盡量選擇內建命令。
因內建命令相比外部命令而言會產生更少的依賴,且多數情況調用內建命令比調用外部命令可以獲得更好的性能(通常外部命令會產生額外的進程開銷)。
正例:
反例:
載入外部庫文件不建議用使用.,建議使用source,已提升可閱讀性。正例:
反例:
除非必要情況,盡量使用單個命令及其參數組合來完成一項任務,而非多個命令加上管道的不必要組合。常見的不建議的用法例如:cat和grep連用過濾字元串; cat和wc連用統計行數; grep和wc連用統計行數等。
正例:
除特殊情況外,幾乎所有函數都不應該使用exit直接退出腳本,而應該使用return進行返回,以便後續邏輯中可以對錯誤進行處理。正例:
反例:
推薦以下工具幫助我們進行代碼的規范:
原文鏈接:http://itxx00.github.io/blog/2020/01/03/shell-standards/
獲取更多的面試題、腳本等運維資料點擊: 運維知識社區 獲取
腳本之---簡訊轟炸機
腳本之---QQ微信轟炸機
ansible---一鍵搭建redis5.0.5集群
elk7.9真集群docker部署文檔
全球最全loki部署及配置文檔
最強安全加固腳本2.0
一鍵設置iptbales腳本