一篇文章從了解到入門shell

1、shell介紹

shell 俗稱叫做殼,計(jì)算機(jī)的殼層,和內(nèi)核是相對(duì)的,用于和用戶交互,接收用戶指令,調(diào)用相應(yīng)的程序。

因此,把shell分為2大類

1.1、圖形界面shell(Graphical User Interface shell 即 GUI shell)

也就是用戶使用GUI和計(jì)算機(jī)核交互的shell,比如Windows下使用最廣泛的Windows Explorer(Windows資源管理器),Linux下的X Window,以及各種更強(qiáng)大的CDE、GNOME、KDE、 XFCE。

他們都是GUI Shell。

1.2、命令行式shell(Command Line Interface shell ,即CLI shell)

也就是通過(guò)命令行和計(jì)算機(jī)交互的shell。

Windows NT 系統(tǒng)下有 cmd.exe(命令提示字符)和近年來(lái)微軟大力推廣的 Windows PowerShell。

Linux下有bash / sh / ksh / csh/zsh等

一般情況下,習(xí)慣把命令行shell(CLI shell)直接稱做shell,以后,如果沒(méi)有特別說(shuō)明,shell就是指 CLI shell,后文也是主要講Linux下的 CLI shell。

2、交互方式

根據(jù)交互方式的不一樣,命令行式shell(CLI shell),又分為交互式shell和非交互式shell。

2.1、交互式shell

交互式模式就是shell等待你的輸入,并且執(zhí)行你提交的命令,然后馬上給你反饋。這種也是我們大多數(shù)時(shí)候使用的。

2.2、非交互式shell

非交互式shell,就是把shell放在寫在一個(gè)文件里面,執(zhí)行的時(shí)候,不與用戶交互,從前往后依次執(zhí)行,執(zhí)行到文件結(jié)尾時(shí),shell也就終止了。

3、shell的種類

在Linux下 ,各種shell百花齊放,種類繁多,不同的shell,也有不同的優(yōu)缺點(diǎn)。

我們要查看當(dāng)前系統(tǒng)下支持的shell,可以讀取/etc/shells文件。

3.1、bash

Bourne Again Shell 用來(lái)替代Bourne shell,也是目前大多數(shù)Linux系統(tǒng)默認(rèn)的shell。

3.2、sh

Bourne Shell 是一個(gè)比較老的shell,目前已經(jīng)被/bin/bash所取代,在很多l(xiāng)inux系統(tǒng)上,sh已經(jīng)是一個(gè)指向bash的鏈接了。

下面是CentOS release 6.5 的系統(tǒng)

3.3、csh/tcsh

C shell 使用的是“類C”語(yǔ)法,csh是具有C語(yǔ)言風(fēng)格的一種shell,tcsh是增強(qiáng)版本的csh,目前csh已經(jīng)很少使用了。

3.4、ksh

最早,bash交互體驗(yàn)很好,csh作為非交互式使用很爽,ksh就吸取了2者的優(yōu)點(diǎn)。

3.5、zsh

zsh網(wǎng)上說(shuō)的目前使用的人很少,但是感覺(jué)使用的人比較多。

zsh本身是不兼容bash的,但是他可以使用仿真模式(emulation mode)來(lái)模擬bash等,基本可以實(shí)現(xiàn)兼容。

在交互式的使用中,目前很多人都是zsh,因?yàn)閦sh擁有很強(qiáng)大的提示和插件功能,炫酷吊炸天。推薦在終端的交互式使用中使用zsh,再安利一個(gè)插件Oh My Zsh

其實(shí)我個(gè)人的理解是,在終端中使用shell,基本上只是調(diào)用各種命令,比如:curl cat ls等等,基本不會(huì)使用到zsh的編程,所以終端中使用zsh是可以的。但是在寫shell腳本的時(shí)候,需要考慮兼容性,

最主流的還是bash shell,所以,后文我們介紹的shell腳本也是bash shell的。

4、shell腳本

4.1、基礎(chǔ)

1

2

#!/bin/bash

echo "Hello World !"

#!:是一個(gè)特殊的標(biāo)記,表明使用啥解釋器來(lái)執(zhí)行,比如這里使用了:/bin/bash 來(lái)執(zhí)行這個(gè)腳本。

#:只用一個(gè)#,就是注釋

echo:輸出

我們把上面的腳本保存成一個(gè)文件, 1.sh 后面的這個(gè)sh是shell腳本的擴(kuò)展名。

然后要怎嚒來(lái)執(zhí)行呢?執(zhí)行一個(gè)shell腳本有很多種方式:

sh 1.sh 這樣可以直接執(zhí)行這個(gè)1.sh

也可以直接 ./1.sh ,但是這種要注意,才編輯好的文件這樣執(zhí)行可能會(huì)報(bào)錯(cuò)

這個(gè)是因?yàn)闆](méi)有這個(gè)腳本沒(méi)有執(zhí)行權(quán)限,運(yùn)行 chmod a+x 1.sh 加上執(zhí)行權(quán)限即可。

這里順帶說(shuō)一下,為啥直接運(yùn)行1.sh不行呢?因?yàn)樗J(rèn)是去PATH里面找程序,當(dāng)前目錄,一般都不在PATH里面。所以直接運(yùn)行1.sh就回報(bào)找不到文件。

還可以使用類似curl?http://xxxxx.xxx/xxx.sh|sh?這樣的方式,來(lái)執(zhí)行遠(yuǎn)程的腳本

根據(jù)測(cè)試,#!/bin/bash 的標(biāo)記,只是針對(duì)第二種方式 ./xxx.sh的方式有效。本文中代碼,第一行均為這個(gè)標(biāo)記,為了節(jié)約篇幅,已經(jīng)省略.

執(zhí)行并獲取返回結(jié)果,有點(diǎn)類似JavaScript 的eval函數(shù)。

1

2

3

#!/bin/bash

dt=`date` #反引號(hào)內(nèi)的字符串會(huì)當(dāng)作shell執(zhí)行 ,并且返回結(jié)果。

echo "dt=${dt}"

4.2、Shell 變量

shell的使用比較簡(jiǎn)單,就像這樣,并且沒(méi)有數(shù)據(jù)類型的概念,所有的變量都可以當(dāng)成字符串來(lái)處理:

1

2

3

#!/bin/bash

myName="tom"

youName="cat"

不需要申明,直接寫就可以了,但是有幾個(gè)點(diǎn)需要特別注意:

等號(hào)兩邊不能有空格!??!特別要注意,非常容易寫錯(cuò)

命名只能使用英文字母,數(shù)字和下劃線,首個(gè)字符不能以數(shù)字開頭。

中間不能有空格,可以使用下劃線(_)。

不能使用標(biāo)點(diǎn)符號(hào)。

不能使用bash里的關(guān)鍵字。

使用變量

ABC="tom"

echo $ABC #使用變量前面加$美元符號(hào)

echo "ABC=$ABC" #可以直接在字符串里面引用

echo "ABC=${ABC}" #但是建議把變量名字用{}包起來(lái)

#只讀變量

ABC="tom"

echo "ABC=${ABC}"

readOnly ABC #設(shè)置只讀

ABC="CAT" #會(huì)報(bào)錯(cuò),因?yàn)樵O(shè)置了只讀,不能修改

刪除變量

ABC="tom"

echo "ABC=${ABC}"

unset ABC #刪除

echo "ABC=$ABC"?

echo "ABC=${ABC}"

從這個(gè)例子當(dāng)中,我們也發(fā)現(xiàn),使用一個(gè)不存在的變量,shell不會(huì)報(bào)錯(cuò),只是當(dāng)作空來(lái)處理。

4.3、Shell 的字符串

使用字符串

NAME="tom"

A=my #你甚至可以不用引號(hào),但是字符串當(dāng)中不能有空格,這種方式也不推薦

B='my name is ${NAME}' #變量不會(huì)被解析

C="my name is ${NAME}" #變量會(huì)解析

echo $A

echo $B

echo $C

執(zhí)行結(jié)果

我們可以發(fā)現(xiàn),這個(gè)字符串的單雙號(hào)和PHP的處理非常類似,單引號(hào)不解析變量,雙引號(hào)可以解析變量。但是都可以處理轉(zhuǎn)義符號(hào)。

A='my\nname\nis\ntom'

B="my\nname\nis\ntom"

echo $A

echo $B

拼接字符串

其實(shí)shell拼接字符串,大概就是2種

一是直接在雙引號(hào)內(nèi)應(yīng)用變量,類似模版字符串

二是直接把字符串寫在一起,不需要類似Java鏈接字符串的“+” 和PHP鏈接字符串的“.”

NAME="TOM"

#使用雙引號(hào)拼接

echo "hello, "$NAME" !" #直接寫在一起,沒(méi)有字符串連接符

echo "hello, ${NAME} !" #填充模版

#使用單引號(hào)拼接

echo 'hello, '$NAME' !' #直接寫在一起,沒(méi)有字符串連接符

echo 'hello, ${NAME} !' #上面已經(jīng)提高過(guò),單引號(hào)里面的變量是不會(huì)解析的

強(qiáng)大的字符串處理

shell中簡(jiǎn)單的處理字符串,可以直接使用各種標(biāo)記,只是比較難記憶,要用的時(shí)候,可以查一下。

ABC="my name is tom,his name is cat"

echo "字符串長(zhǎng)度=${#ABC}" # 取字符串長(zhǎng)度

echo "截取=${ABC:11}" # 截取字符串, 從11開始到結(jié)束

echo "截取=${ABC:11:3}" # 截取字符串, 從11開始3個(gè)字符串

echo "默認(rèn)值=${XXX-default}" #如果XXX不存在,默認(rèn)值是default

echo "默認(rèn)值=${XXX-$ABC}" #如果XXX不存在,默認(rèn)值是變量ABC

echo "從開頭刪除最短匹配=${ABC#my}" # 從開頭刪除 my 匹配的最短字符串

echo "從開頭刪除最長(zhǎng)匹配=${ABC##my*tom}" # 從開頭刪除 my 匹配的最長(zhǎng)字符串

echo "從結(jié)尾刪除最短匹配=${ABC%cat}" # 從結(jié)尾刪除 cat 匹配的最短字符串

echo "從結(jié)尾刪除最長(zhǎng)匹配=${ABC%%,*t}" # 從結(jié)尾刪除 ,*t 匹配的最長(zhǎng)字符串

echo "替換第一個(gè)=${ABC/is/are}" #替換第一個(gè)is

echo "替換所有=${ABC//is/are}" #替換所有的is

這里只是介紹了比較常用的一些字符串處理,實(shí)際shell支持的還有很多。

4.4、數(shù)組

Bash Shell 也是支持?jǐn)?shù)組的,與絕大部分語(yǔ)言一樣,數(shù)組下標(biāo)從0開始。不過(guò)需要注意的是,它只支持一維數(shù)組。

定義一個(gè)數(shù)組,用小括號(hào)闊氣來(lái),當(dāng)中用“空格”分割,就像下面這樣:

1

array=("item0" "item1" "item2")

也可以根據(jù)下標(biāo)來(lái)定義元素

array[0]="new_item0"

array[1]="new_item1"

array[2]="new_item2"

array[4]="new_item4" #數(shù)組下標(biāo)可以是不連續(xù)的

讀取數(shù)組元素,和變量類似

echo ${array[0]}

echo "array[0]=${array[0]}"

獲取數(shù)組所有的元素

echo "數(shù)組的元素為: ${array[*]}"

echo "數(shù)組的元素為: ${array[@]}"

獲取數(shù)組的長(zhǎng)度

echo "數(shù)組的長(zhǎng)度為: ${#array[*]}"

echo "數(shù)組的長(zhǎng)度為: ${#array[@]}"

4.5、輸入輸出

4.5.1、echo

在上文中,其實(shí)我們已經(jīng)到多次,就是:echo “字符串” 來(lái)輸出,一個(gè)很簡(jiǎn)單的例子

echo "Hello world!"

如果當(dāng)中包含特殊符號(hào),可以使用轉(zhuǎn)義等:


echo "Hello \nworld!"

echo "\"Hello\""

echo '"Hello"' #當(dāng)然,也可以這樣,單引號(hào)不轉(zhuǎn)義,上文提到過(guò)

echo `date` #打印執(zhí)行date的結(jié)果

echo -n "123" #加-n? 表示不在末尾輸出換行

echo "456"

echo -e "\a處理特殊符號(hào)" #-e 處理特殊符號(hào)

-n?讓echo輸出結(jié)束以后,在默認(rèn)不輸出換行符

-e?讓echo處理特殊符號(hào),比如:

符號(hào)作用

\a發(fā)出警告聲

\b刪除前一個(gè)字符

\c后不加上換行符號(hào)

\f換行但光標(biāo)仍舊停留在原來(lái)的位置

\n換行且光標(biāo)移至行首

\r光標(biāo)移至行首,但不換行

\t插入tab

上面的特殊符號(hào),寫到mac的shell腳本里面要注意,執(zhí)行的時(shí)候,要用bash執(zhí)行才有效 ,sh無(wú)效。

當(dāng)然,你也可以玩一點(diǎn)更有趣的,就是我們隨時(shí)在終端中看到的五顏六色的文字:

echo -e "\033[31m 紅色前景 \033[0m 缺省顏色"

echo -e "\033[41m 紅色背景 \033[0m 缺省顏色"

其中

\033[是一個(gè)特殊標(biāo)記,表示終端轉(zhuǎn)義開始,

31m表示使用紅色字體,你也可以使用其他顏色,[30-39]是前景顏色,[40-49]是背景顏色。

\033[0m回復(fù)到缺省設(shè)置

還可以有一些其他的動(dòng)作


echo -e "\033[2J" #清除屏幕

echo -e "\033[0q" #關(guān)閉所有的鍵盤指示燈

echo -e "\033[1q" #設(shè)置"滾動(dòng)鎖定"指示燈(Scroll Lock)

echo -e "\033[2q" #設(shè)置"數(shù)值鎖定"指示燈(Num Lock)

echo -e "\033[1m" #設(shè)置高亮度

echo -e "\033[4m" #下劃線

echo -e "\033[7m" #反顯

echo -e "\033[y;xH" #設(shè)置光標(biāo)位置

其他更多的特殊碼請(qǐng)自行查詢。

4.5.2、read

有輸出,必然有輸入,read命令接收標(biāo)準(zhǔn)輸入的輸入。


read name

echo "my name is ${name}"

可以使用-p給一個(gè)輸入提示


read -p "please input your name:" name

echo "my name is ${name}"

如果沒(méi)有指定輸入的變量,會(huì)把輸入放在環(huán)境標(biāo)量REPLY中


read -p "please input your name:"

echo "my name is ${REPLY}"

計(jì)時(shí)輸入,如果一段時(shí)間沒(méi)有輸入 ,就直接返回,使用-t 加時(shí)間


read -t 3 -p "please input your name in 3 senconds:" name

指定輸入字符個(gè)數(shù),使用-n ,后面的是輸入字符個(gè)數(shù)


read -n 1 -p "Are you sure [Y/N]?" isYes

默讀(輸入不再監(jiān)視器上顯示),加一個(gè)-s參數(shù)。


read? -s? -p "Enter your password:" password

4.5.3、printf

echo已經(jīng)比較強(qiáng)大,但是有的時(shí)候,我們需要用到字符串模版輸出,printf就比較好用了,他類似C里面的printf程序。

語(yǔ)法是:printf format-string [arguments…]

比如我們要輸出一個(gè)表格


printf "%-10s %-8s %-4s\n" 姓名 性別 體重kg?

printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234

printf "%-10s %-8s %-4.2f\n" 楊過(guò) 男 48.6543

printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876

運(yùn)行結(jié)果

%s %c %d %f都是格式替代符

%-10s 指一個(gè)寬度為10個(gè)字符(-表示左對(duì)齊,沒(méi)有則表示右對(duì)齊),至少顯示10字符寬度,如果不足則自動(dòng)以空格填充,超過(guò)不限制。

%-4.2f 指格式化為小數(shù),其中.2指保留2位小數(shù)。

4.5.4、重定向

大多數(shù) UNIX 系統(tǒng)命令從你的終端接受輸入并將所產(chǎn)生的輸出發(fā)送回到您的終端。一個(gè)命令通常從一個(gè)叫標(biāo)準(zhǔn)輸入的地方讀取輸入,默認(rèn)情況下,這恰好是你的終端。同樣,一個(gè)命令通常將其輸出寫入到標(biāo)準(zhǔn)輸出,默認(rèn)情況下,這也是你的終端。

命令作用

command > file將輸出重定向到 file。

command < file將輸入重定向到 file。

command >> file將輸出以追加的方式重定向到 file。

n > file將文件描述符為 n 的文件重定向到 file。

n >> file將文件描述符為 n 的文件以追加的方式重定向到 file。

n >& m將輸出文件 m 和 n 合并。

n <& m將輸入文件 m 和 n 合并。

<< tag將開始標(biāo)記 tag 和結(jié)束標(biāo)記 tag 之間的內(nèi)容作為輸入。

需要注意的是文件描述符 0 通常是標(biāo)準(zhǔn)輸入(STDIN),1 是標(biāo)準(zhǔn)輸出(STDOUT),2 是標(biāo)準(zhǔn)錯(cuò)誤輸出(STDERR)。

輸出到文件

1

2

echo "test">text.txt #直接輸出

echo "test">>text.txt #追加在text.txt后面

重定向輸入


read a <<EOF

"測(cè)試"

EOF

echo "a=$a"

來(lái)個(gè)比較過(guò)分的


cat? < 1.sh > text.txt

把1.sh文件的內(nèi)容出入到cat,然后cat在輸出到text.txt中,相當(dāng)于,把1.sh的內(nèi)容輸出到text.txt中了

還有一種用法,把標(biāo)準(zhǔn)錯(cuò)誤直接輸出到標(biāo)準(zhǔn)輸出,并且輸出到文件file


command > file 2>&1

/dev/null 文件

這個(gè)是一個(gè)特殊文件,他是一個(gè)黑洞,寫入到它的內(nèi)容都會(huì)被丟棄,如果我們不關(guān)心程序的輸出,可以這樣


command > /dev/null 2>&1

4.6、條件判斷(if)

和其他語(yǔ)言一樣,shell也有條件判斷

單分支:


if condition

then

? ? command1

? ? command2

? ? ...

fi

雙分支:


if condition

then

? ? command1

? ? command2

? ? ...

else

? ? command

fi

多分支:


if condition1

then

? ? command1

elif condition2

then

? ? command2

else

? ? commandN

fi

比如


if [ "2" == "2" ]; then # "2" 的2邊都有空格,不能省略 ,寫在一行,條件后面加一個(gè)分號(hào)

echo "2==2"

else

echo "2!=2"

fi

需要特別注意:[ “2” == “2” ] 其中的”==”兩邊都有空格,不能省略,否則結(jié)果不正確。

判斷普通文件是否存在


if [ -f "1.sh" ]; then # 判斷一個(gè)普通文件是否存在

echo "1.sh 存在"

fi

判斷目錄是否存在


if [ -d "1.sh" ]; then # 判斷一個(gè)目錄是否存在

echo "1.sh 存在"

fi

判斷字符串長(zhǎng)度為0


a=""

if [ -z $a ]; then

echo "a為空"

fi

4.7、()、(())、[]、[[]]和{}

在shell中,有幾個(gè)符號(hào)要非常注意,用的也比較多,不要搞混了,搞混了,邏輯運(yùn)算很容易出錯(cuò)

4.7.1、單小括號(hào)()

命令組

括號(hào)中的命令將會(huì)新開一個(gè)子shell順序執(zhí)行,所以括號(hào)中的變量不能夠被腳本余下的部分使用。括號(hào)中多個(gè)命令之間用分號(hào)隔開,最后一個(gè)命令可以沒(méi)有分號(hào),各命令和括號(hào)之間不必有空格。


a="123"

(echo "123";a="456";echo "a=$a")

echo "a=$a

命令替換

發(fā)現(xiàn)了$(cmd)結(jié)構(gòu),便將$(cmd)中的cmd執(zhí)行一次,得到其標(biāo)準(zhǔn)輸出,再將此輸出放到原來(lái)命令。

用于初始化數(shù)組

如:array=(a b c d)

4.7.2、雙小括號(hào)(())

運(yùn)算擴(kuò)展,比如,你可以


a=$((4+5))

echo "a=$a"

做數(shù)值運(yùn)算,重新定義變量

1

2

3

a=5

((a++))

echo "a=$a"

用于算術(shù)運(yùn)算比較


if ((1+1>1));then

? echo "1+1>1"

fi

4.7.3、單中括號(hào)[]

用于字符串比較

需要注意,用于字符串比較,運(yùn)算符只能是 ==和!=,需要注意,運(yùn)算符號(hào)2邊必須有空格,不然結(jié)果不正確?。?!比如:


if [ "2" == "2" ]; then # "2" 的2邊都有空格,不能省略

echo "2==2"

else

echo "2!=2"

fi

用于整數(shù)比較

需要注意,整數(shù)比較,只能用-eq,-gt這種形式,不能直接使用大于(>)小于(<)符號(hào)。只能用于整形。


if [ 2 -eq 2 ]; then

echo "2==2"

else

echo "2!=2"

fi

符號(hào)表

符號(hào)運(yùn)算

-eq等于

-ne不等于

-gt大于

-ge大于等于

-lt小于

-le小于等于

多個(gè)邏輯組合

-a?表示and 與運(yùn)算

-o?表示or 或運(yùn)算


if [ "2" == "2" -a "1" == "1" ]; then #注意,在這里,不能是[ "2" == "2" ] -a [ "1" == "1" ] 會(huì)報(bào)錯(cuò)

echo "ok"

fi

4.7.4、雙中括號(hào)[[]]

[[是 bash 程序語(yǔ)言的關(guān)鍵字。并不是一個(gè)命令,[[ ]] 結(jié)構(gòu)比[ ]結(jié)構(gòu)更加通用。

字符串匹配時(shí)甚至支持簡(jiǎn)單的正則表達(dá)式


if [[ "123" == 12* ]]; then #右邊是正則不需要引號(hào)

? ? echo "ok"

fi


if [[? 2.1 > 1.1 ]]; then

? ? echo "ok"

fi

多個(gè)邏輯判斷

可以直接使用&&、||做邏輯運(yùn)算,并且可以在多個(gè)[[]]之間進(jìn)行運(yùn)算


if [[? 1.1 > 1.1 ]] || [[ 1.1 == 1.1 ]]; then

? ? echo "ok"

fi

4.7.5、大括號(hào){}

統(tǒng)配擴(kuò)展

1

touch file_{1..5}.txt #創(chuàng)建new_1.txt new_2.txt new_3.txt new_4.txt new_5.txt? 5個(gè)文件

4.8、循環(huán)

4.8.1、for循環(huán)

語(yǔ)法格式為:


for a in "item1" "item2" "item3"

do

? echo $a

done

輸出當(dāng)前目錄下 .sh結(jié)尾的文件


for a in `ls ./`

do

? if [[ $a == *.sh ]]

? then

? ? echo $a

? fi

done

4.8.2、for循環(huán)

語(yǔ)法


while condition

do

? ? command

done

我們要輸出1-10000


int=1;

while(($int<=10000))

do

? echo $int

? ((int++))

done

4.8.3、until循環(huán)

語(yǔ)法


until condition

do

? ? command

done

用法類似,這里不再贅述。

循環(huán)中 continue命令與break作用和其他語(yǔ)言中類似。

4.9、case

case和其他語(yǔ)言switch類型,多分支,選擇一個(gè)匹配。匹配發(fā)現(xiàn)取值符合某一模式后,其間所有命令開始執(zhí)行直至 ;;,有點(diǎn)類型Java的break。如果無(wú)一匹配模式,使用星號(hào) * 捕獲該值,再執(zhí)行后面的命令。


echo '輸入 1 到 4 之間的數(shù)字:'

echo '你輸入的數(shù)字為:'

read aNum

case $aNum in

? ? 1)? echo '你選擇了 1'

? ? ;;

? ? 2)? echo '你選擇了 2'

? ? ;;

? ? 3)? echo '你選擇了 3'

? ? ;;

? ? 4)? echo '你選擇了 4'

? ? ;;

? ? *)? echo '你沒(méi)有輸入 1 到 4 之間的數(shù)字'

? ? ;;

esac

4.10、函數(shù)

shell也可以用戶定義函數(shù),然后在shell腳本中可以隨便調(diào)用。

注意:所有函數(shù)在使用前必須定義。這意味著必須將函數(shù)放在腳本開始部分,直至shell解釋器首次發(fā)現(xiàn)它時(shí),才可以使用。調(diào)用函數(shù)僅使用其函數(shù)名即可。

語(yǔ)法格式如下:


[function] funname()

{

? ? cmd....

? ? [return int]

}

一個(gè)最簡(jiǎn)單的函數(shù)


Line(){

? echo "--------分割線--------"

}

echo "123"

Line

echo "456"

在Shell中,調(diào)用函數(shù)時(shí)可以向其傳遞參數(shù)。

在函數(shù)體內(nèi)部,通過(guò) $n 的形式來(lái)獲取參數(shù)的值,例如,$1表示第一個(gè)參數(shù),$2表示第二個(gè)參數(shù)…

調(diào)用的時(shí)候 ,函數(shù)名,參數(shù)直接用空格分割開。

帶參數(shù)的函數(shù)示例:


out(){

? echo "1-->$1"

? echo "2-->$2"

}

out 1 2 #調(diào)用的之后

還有一些其他的特殊符號(hào)需要注意

符號(hào)作用

$#傳遞到腳本的參數(shù)個(gè)數(shù)

$*以一個(gè)單字符串顯示所有向腳本傳遞的參數(shù)

$$腳本運(yùn)行的當(dāng)前進(jìn)程ID號(hào)

$!后臺(tái)運(yùn)行的最后一個(gè)進(jìn)程的ID號(hào)

$@與$*相同,但是使用時(shí)加引號(hào),并在引號(hào)中返回每個(gè)參數(shù)。

$?顯示最后命令的退出狀態(tài)。0表示沒(méi)有錯(cuò)誤,其他任何值表明有錯(cuò)誤。

所以我們可以寫一個(gè)代碼參數(shù),返回值的函數(shù)


out(){

echo "全部參數(shù)$*"

? for item in $*

? do

? ? echo "$item"

? done

? return $# #這類返回參數(shù)個(gè)數(shù),返回值必須是整數(shù)

}

out this is perfect

echo "函數(shù)返回值:$?"

4.11、shell傳遞參數(shù)

我們可以在執(zhí)行 Shell 腳本時(shí),向腳本傳遞參數(shù),腳本內(nèi)獲取參數(shù)的格式為:$n。n 代表一個(gè)數(shù)字,1 為執(zhí)行腳本的第一個(gè)參數(shù),2 為執(zhí)行腳本的第二個(gè)參數(shù),以此類推……

除了參數(shù)可以使用特殊符號(hào),也可以使用上文中函數(shù)所使用的特殊符號(hào),這里不再贅述


echo "執(zhí)行的文件名:$0";

echo "全部參數(shù):$*"

echo "參數(shù)個(gè)數(shù):$#"

echo "第一個(gè)參數(shù)為:$1";

echo "第二個(gè)參數(shù)為:$2";

echo "第三個(gè)參數(shù)為:$3";

5、其他實(shí)用技巧

shell腳本,他本身的功能并不強(qiáng)大,強(qiáng)大的是他可以調(diào)用其他程序,而在Linux下,系統(tǒng)自帶的就有非常多的強(qiáng)大工具可以調(diào)用。

5.1、后臺(tái)執(zhí)行

后臺(tái)執(zhí)行一個(gè)腳本只需要在后面加上&符號(hào)即可,我們先用之前學(xué)習(xí)的,寫一個(gè)腳本,1s輸出一個(gè)數(shù)字


#!/bin/bash

int=1

while :

do

? echo $int

? ((int++))

? sleep 1s #睡眠一秒

done

我們執(zhí)行sh d.sh & 我們發(fā)現(xiàn),的確會(huì)后臺(tái)輸出,但是會(huì)輸出到當(dāng)前控制臺(tái),我們可以用之前學(xué)的重定向,把輸出重定向到文件

sh d.sh > out.log 2>&1 &

這樣就把輸出和錯(cuò)誤重新定向到out.log文件了

但是,我們發(fā)現(xiàn),關(guān)閉終端以后,文件就不輸出了。

當(dāng)我們端口連接遠(yuǎn)程主機(jī)的session或者關(guān)閉當(dāng)前終端的時(shí)候, 會(huì)產(chǎn)生一個(gè)SIGHUP信號(hào) ,導(dǎo)致程序退出,我們可以使用nuhup來(lái)忽略這個(gè)信號(hào) ,達(dá)到真正的后臺(tái)。

nuhup sh d.sh > out.log 2>&1 &

這樣啟動(dòng)程序,就可以打到真正后臺(tái)運(yùn)行了。

那么問(wèn)題來(lái)了,我們驗(yàn)證程序在后臺(tái)運(yùn)行呢?要怎嚒結(jié)束后臺(tái)程序呢?請(qǐng)繼續(xù)看。

5.2、cat

在本文中,我們已經(jīng)多次用到cat,他的作用就是讀取文件輸出到標(biāo)準(zhǔn)輸出上,也就是我們的終端。

語(yǔ)法是:

cat [option] file

我們也可以使用:cat -n file ,來(lái)輸出行號(hào)。

5.2、tail

類似上面的例子,我們要驗(yàn)證程序是不是在后臺(tái),每一秒輸出一個(gè)數(shù)字到文件,使用cat讀取,需要不斷的多次查看,一次cat只能輸出一次。

tail非常適合查看這種日志類文件,他的作用是讀取文件末尾幾行輸出到標(biāo)準(zhǔn)輸出上。

tail out.log

默認(rèn)顯示10行,可以使用參數(shù)-n指定行數(shù)

tail -20 out.log

顯示文件末尾20行

tail -f out.log

持續(xù)監(jiān)控文件out.log,如果有變化,他會(huì)試試的顯示在我們的屏幕上面。

5.3、ps

ps,查詢進(jìn)程

這個(gè)命令參數(shù)比較多,列舉幾個(gè)比較常用的

參數(shù)作用

a顯示終端上的所有進(jìn)程,包括其他用戶的進(jìn)程。

u顯示面向用戶的格式信息。

x顯示沒(méi)有控制終端的進(jìn)程。

一般查詢,使用 ps aux就可以了,查詢出來(lái)比較多,可以篩選一下。

這里我們使用 ps u 就可以查詢出我們剛才開啟的后臺(tái)進(jìn)程了。

我們看到我們剛才啟動(dòng)的程序PID為7523,

使用kill命令就可以殺死他了

5.4、kill

kill命令比較簡(jiǎn)單,就是根據(jù)PID結(jié)束一個(gè)程序,比如我們已經(jīng)查詢到,我們開的后臺(tái)進(jìn)行是7523,要結(jié)束他可以使用:

kill 7523

以上是常用用法,其實(shí)kill是給程序發(fā)送一個(gè)信號(hào),上面的程序給會(huì)程序發(fā)送一個(gè)SIGTERM信號(hào),程序收到這個(gè)信號(hào),完成資源的釋放,就退出了。

但是也有程序不聽話,收到信號(hào)就是不退出,這個(gè)時(shí)候,就要強(qiáng)制他退出,使用9號(hào)命令(SIGKILL),強(qiáng)制殺死他。

簡(jiǎn)單的說(shuō)

kill PID 是告訴程序,你應(yīng)該退出了,請(qǐng)自己退出。

kill -9 PID ,是直接告訴程序,你被終結(jié)了,這個(gè)命令信號(hào),不能被抓取或者忽略。

6、總結(jié)

shell使用的比較少,但是特別強(qiáng)大;

shell對(duì)語(yǔ)法比較敏感,并且應(yīng)為解釋器很多,每個(gè)解釋器語(yǔ)法標(biāo)準(zhǔn)也可能不完全一致;

使用到的編號(hào)、編碼、參數(shù)特別多,并且都是簡(jiǎn)寫,很多記不住。其實(shí)不用死記硬背,記住有這個(gè)功能就可以了,需要用到的時(shí)候再查詢。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、Python簡(jiǎn)介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡(jiǎn)介】: Python 是一個(gè)...
    _小老虎_閱讀 6,328評(píng)論 0 10
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,711評(píng)論 0 5
  • 什么是運(yùn)維 術(shù)語(yǔ)名詞 IDC--(Internet Data Center)互聯(lián)網(wǎng)數(shù)據(jù)中心,主要服務(wù)包括整機(jī)租用、...
    lyh165閱讀 2,877評(píng)論 0 19
  • 用了caffe有一段時(shí)間了,感覺(jué)自己寫shell腳本的能力有待提高,特地從菜鳥筆記處系統(tǒng)的看了一遍,其實(shí)學(xué)習(xí)基礎(chǔ)就...
    yichen_china閱讀 1,879評(píng)論 2 30
  • 第 2 章 SHELL 基礎(chǔ)知識(shí)2.1 shell腳本我們?cè)谏厦婧?jiǎn)單介紹了一下什么是shell腳本,現(xiàn)在我們來(lái)進(jìn)一...
    LiWei_9e4b閱讀 1,643評(píng)論 0 0

友情鏈接更多精彩內(nèi)容