【1】交互方式、非交互方式、Shell腳本是什麼?linux
常常與linux打交道,確定對shell這個詞不陌生。不明白shell意思的,能夠自行翻譯:外殼、去殼。shell
這個翻譯結果怎麼能夠與計算機系統聯繫起來呢?看不懂?小程序
爲了幫助理解shell這個詞,請看下圖:vim
計算機系統,最內層(本質)的是硬件,而後硬件會被系統核心層包住,而在系統核心外層的就是所謂的shell,再而後shell外層的就是咱們接觸最多且最容易理解的應用程序。windows
shell實際上是一個命令解釋器,做用是解釋用戶輸入的命令和程序,命令和程序能夠理解成上圖中的應用程序。安全
linux系統中的那些命令其實也都是一個個的小程序,只不過執行的是系統的應用功能。bash
當咱們在系統的終端中輸入一條命令,能夠立馬看到一條或者幾條系統回覆咱們的信息,其實就是shell在幫咱們回覆,因此shell能夠稱之爲命令解釋器。服務器
而這種從鍵盤一輸入命令,就立馬獲得相應的回覆信息,叫做交互的方式。函數
瞭解了shell以後,再來了解下shell腳本。若是咱們的命令或應用程序不在命令行直接執行,而想經過一個程序文件來執行時,這個程序文件就被稱之爲shell腳本。oop
shell腳本里面一般內置了多條命令,有的還包含控制語句,好比if和else的條件控制語句,for的循環控制語句等。
這些內置在一個shell腳本中的命令一般是一次性執行完成,不會不停的返回信息給用戶,這種經過文件執行腳本的方式稱之爲非交互方式。
shell腳本相似於windows下的批處理,但它比批處理要強大一些,如今windows下有一個叫作power shell的功能其實和linux下的shell功能媲美。
在文本中輸入一系列的命令、控制語句和變量,這一切有機的結合起來就造成了功能強大的shell腳本。
平常工做中,常常須要使用多個命令來完成一項任務,能夠添加這些全部命令在一個文本文件(Shell腳本)來統一完成這些平常工做任務。
【2】什麼是默認登陸shell,如何改變指定用戶的登陸shell?
登陸shell是能夠用戶登陸使用的,好比/bin/bash, /bin/sh, /bin/csh......
通常Linux默認的用戶shell都是bash,也就是你能夠登陸進去寫命令。
非登陸shell:經典的/bin/nologin就是一個非登陸shell,也就是說若是一個用戶默認的是它,這個用戶即便登陸進linux也沒法使用linux。
shell是用戶和計算機交流的媒介,登陸shell保證用戶和計算機交流,非登陸shell沒法讓計算機和用戶交流。
關於用戶的默認登陸shell是在/etc/passwd文件中記錄的。本地系統示例以下:
非登陸shell有其特定的用途:好比一個用linux搭建的ftp服務器,建立了多個用戶,能夠將這些用戶默認shell改爲nologin。
這樣一來,這些用戶雖然是linux上的用戶卻沒法登陸進linux主機,只能進入ftp服務器,這樣也保證了安全!
在Linux操做系統,「/bin/bash」是默認登陸shell,是在建立用戶時分配的。
使用chsh命令能夠改變默認的shell。示例以下所示:
# chsh <用戶名> -s <新shell>
# chsh zhangsan -s /bin/sh
固然,也能夠直接經過修改/etc/passwd文件中對應用戶的默認shell。
查看系統中有哪些shell,利用命令:cat /etc/shells
示例以下(本地系統中有六種shell):
【3】能夠在shell腳本中使用哪些類型的變量?
在shell腳本,咱們可使用兩種類型的變量:
(1)系統定義變量
(2)用戶定義變量
系統變量是由系統系統本身建立的。這些變量一般由大寫字母組成,能夠經過「set」命令查看。
用戶變量由系統用戶來生成和定義,變量的值能夠經過命令「echo $<變量名>」查看。
shell變量的做用域能夠分爲三種:
(1)有的變量只能在函數內部使用,叫作局部變量(local variable)
(2)有的變量能夠在當前shell進程中使用,叫作全局變量(global variable)
(3)有的變量還能夠在子進程中使用,叫作環境變量(environment variable)
【4】如何將標準輸出和錯誤輸出同時重定向到同一位置?
這裏有兩個方法來實現:
(1)方法一:2>&1
示例:# ls /usr/share/doc > log.txt 2>&1
前半部分 ls /usr/share/doc > log.txt 很容易理解,那麼後面的 2>&1 是怎麼回事呢?
要解釋這個問題,還得提到文件重定向。假定已經知道 > 和 < 是文件重定向符。那麼1和2是什麼?
在shell中,每一個進程都和三個系統文件相關聯:
(0)標準輸入stdin
(1)標準輸出stdout
(2)標準錯誤stderr
三個系統文件的文件描述符分別爲0、一、2。因此,這裏 2>&1 的意思就是將標準錯誤也輸出到標準輸出當中。
& 表示「等同於」的意思,2>&1,表示2的輸出重定向等同於1。
實際上,> 就至關於 1> 也就是重定向標準輸出,不包括標準錯誤。
而經過 2>&1 就將標準錯誤重定向到標準輸出了(stderr已做爲stdout的副本),那麼再使用>重定向就會將標準輸出和標準錯誤信息一同重定向了。
若是隻想重定向標準錯誤到文件中,則可使用 2> file。
(2)方法二:&>
示例:# ls /usr/share/doc &> log.txt
& 是一個描述符,若是1或2前不加&,會被當成一個普通文件。
1>&2 把標準輸出重定向到標準錯誤。
2>&1 把標準錯誤輸出重定向到標準輸出。
&> filename 把標準輸出和標準錯誤輸出都重定向到文件filename中
摘錄同問:Linux重定向中 >&2 怎麼理解?
問題補充:echo "abdefghijklmn" >&2 怎麼理解?
問題解答:>&2 即 1>&2 也就是把結果輸出到和標準錯誤同樣;以前若是有定義標準錯誤重定向到某log文件,那麼標準輸出也重定向到這個log文件。
如:ls 2>a1 >&2 (等同 ls >a1 2>&1)
把標準輸出和標準錯誤都重定向到a1,終端上看不到任何輸出信息。
【5】shell腳本中「if」語法如何嵌套?
基礎語法以下:
if [ 條件 ]
then
命令1
命令2
…
else
if [ 條件 ]
then
命令1
命令2
…
else
命令1
命令2
…
fi
fi
if語法示例以下:
#!/bin/bash a=100 b=200 echo "a : "$a echo "b : "$b if [ $a == $b ] then echo "a 等於 b" elif [ $a -gt $b ] then echo "a 大於 b" elif [ $a -lt $b ] then echo "a 小於 b" else echo "沒有符合的條件" fi
if語法輸出結果:
a : 100
b : 200
a 小於 b
if嵌套語法示例以下:
#!/bin/bash a=100 b=200 echo "a : "$a echo "b : "$b if [ $a == $b ] then echo "a 等於 b" else if [ $a -gt $b ] then echo "a 大於 b" else if [ $a -lt $b ] then echo "a 小於 b" else echo "沒有符合的條件" fi fi fi
if嵌套語法輸出結果:
a : 100
b : 200
a 小於 b
【6】shell腳本中「$?」標記的用途是什麼?
在寫一個shell腳本時,若想要檢查前一命令是否執行成功,在if條件中使用「$?」能夠來檢查前一命令的結束狀態。
簡單的例子以下:
若是結束狀態是0,說明前一個命令執行成功。
若是結束狀態不是0,說明命令執行失敗。
【7】在shell腳本中如何比較兩個數字?
在if-then中使用測試命令(-gt等)來比較兩個數字。
-gt示例以下:
#!/bin/bash x=10 y=20 if [ $x -gt $y ] then echo "x is greater than y" else echo "y is greater than x" fi # 輸出 # y is greater than x
test示例以下:
#!/bin/bash num1=$[2*3] num2=$[1+5] if test $[num1] -eq $[num2] then echo '兩個數字相等!' else echo '兩個數字不相等!' fi # 輸出 # 兩個數字相等!
【8】shell腳本中break命令的做用?
break命令一個簡單的用途是退出執行中的循環。
能夠在while和until循環中使用break命令跳出循環。
從while循環中跳出,示例以下:
#!/bin/bash a=0 while [ $a -lt 10 ] do echo $a a=`expr $a + 1` if [ $a -gt 8 ] then echo "break" break fi done # 輸出 0 1 2 3 4 5 6 7 8 break
從until循環中跳出,示例以下:
#!/bin/bash a=0 until [ ! $a -lt 10 ] do echo $a a=`expr $a + 1` if [ $a -gt 8 ] then break fi done # 輸出 0 1 2 3 4 5 6 7 8
從 for 循環中跳出,示例以下:
#!/bin/bash for loop in 1 2 3 4 5 do echo "The value is: $loop" if [ $loop == 4 ] then echo "break" break fi done # 輸出 The value is: 1 The value is: 2 The value is: 3 The value is: 4 break
如上三種跳出方式。
【9】shell腳本中continue命令的做用?
continue命令不一樣於break命令,它只跳出當前循環的迭代,而不是整個循環。
continue命令不少時候是頗有用的,例如錯誤發生,但咱們依然但願繼續執行大循環的時候。
示例以下:
#!/bin/bash for i in `seq 1 5` do echo $i if [ $i == 3 ] then continue fi echo $i done echo $i # 輸出 1 1 2 2 3 4 4 5 5 5
如上示例。
【10】shell腳本中case語句的語法?
基礎語法以下:
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
case語法示例以下(用vim 新建文件cash.sh,輸入內容):
#!/bin/bash echo '輸入 1 到 4 之間的數字:' echo '你輸入的數字爲:' read aNum case $aNum in 1) echo '你選擇了 1' ;; 2) echo '你選擇了 2' ;; 3) echo '你選擇了 3' ;; 4) echo '你選擇了 4' ;; *) echo '你沒有輸入 1 到 4 之間的數字' ;; esac
如上腳本,執行./case.sh 或 sh case.sh
【11】shell腳本中while循環語法?
如同for循環,while循環只要條件成立就重複它的命令塊。
不一樣於for循環,while循環會不斷迭代,直到它的條件不爲真。
基礎語法:
while [ 條件 ]
do
命令…
done
【12】如何使腳本可執行?
使用chmod命令來使腳本可執行。示例以下:
# chmod a+x myshell.sh
【13】「#!/bin/bash」的做用?
#!/bin/bash是shell腳本的第一行,稱爲釋伴(shebang)行。
這裏#符號叫作hash,而!叫作bang。它的意思是命令經過 /bin/bash 來執行。
【14】shell腳本中for循環語法?
for循環的基礎語法:
for 變量 in 循環列表
do
命令1
命令2
…
最後命令
done
【15】如何調試shell腳本?
使用'-x'參數(sh -x myshell.sh)能夠調試shell腳本。
如上面例子中的case.sh腳本,調試結果以下:
如上。
【16】shell腳本如何比較字符串?
test命令能夠用來比較字符串。測試命令會經過比較字符串中的每個字符來比較。
參數 說明
= 等於則爲真
!= 不相等則爲真
-z 字符串 字符串的長度爲零則爲真
-n 字符串 字符串的長度不爲零則爲真
示例以下(用vim新建test.sh文件,輸入以下內容):
#!/bin/bash num1="abcdef" num2="abcdefg" if test $num1 = $num2 then echo '兩個字符串相等!' else echo '兩個字符串不相等!' fi if test $num1 != $num2 then echo '兩個字符串不相等!' else echo '兩個字符串相等!' fi if test -z "$num1" then echo 'num1字符串長度爲0' else echo 'num1字符串長度不爲0' fi num2= if test -n "$num2" then echo 'num2字符串長度不爲0' else echo 'num2字符串長度爲0' fi # 輸出 # 兩個字符串不相等! # 兩個字符串不相等! # num1字符串長度不爲0 # num2字符串長度爲0
如上內容。
【17】Bourne shell(bash) 中有哪些特殊的變量?
下面的表列出了Bourne shell爲命令行設置的特殊變量。
內建變量 解釋
$0 當前腳本的文件名
$n 傳遞給腳本或函數的參數。n是一個數字,表示第幾個參數。例如,第一個參數是$1,第二個參數是$2。
$# 傳遞給腳本或函數的參數個數。
$* 傳遞給腳本或函數的全部參數。
$@ 傳遞給腳本或函數的全部參數。被雙引號(" ")包含時,與 $* 稍有不一樣。可參見下文第【26】問。
$$ 當前shell進程ID。對於shell腳本,就是這些腳本所在的進程ID。
示例以下:
#!/bin/bash echo "0:$0" echo "1:$1" echo "2:$2" echo "3:$3" echo "4:$4" echo "5:$5" echo "6:$6" echo "7:$7" echo "8:$8" echo "9:$9" echo "#:$#" echo "*:$*" echo "@:$@" echo "$:$$"
輸出結果:
如上過程。
【18】在shell腳本中,如何測試文件?
test命令能夠用來測試文件。
test命令基礎用法以下表格:
test 用法
-d 文件名 若是文件存在而且是目錄,返回true
-e 文件名 若是文件存在,返回true
-f 文件名 若是文件存在而且是普通文件,返回true
-r 文件名 若是文件存在並可讀,返回true
-s 文件名 若是文件存在而且不爲空,返回true
-w 文件名 若是文件存在並可寫,返回true
-x 文件名 若是文件存在並可執行,返回true
示例以下:
#!/bin/bash if test -e ./shellarg.sh then echo '文件已存在!' else echo '文件不存在!' fi
輸出結果:
如上。
【19】在shell腳本中,如何寫入註釋?
註釋能夠用來描述一個腳本能夠作什麼和它是如何工做的。每一行註釋以#開頭。
示例以下:
#!/bin/bash
# This is a command
【20】如何讓shell腳本獲得來自終端的輸入?
read命令能夠讀取來自終端(使用鍵盤)的數據。read命令獲得用戶的輸入並置於你給出的變量中。
示例以下:
#!/bin/bash echo ‘please enter your name’ read name echo 「my Name is $name」
輸出結果:
如上。
【21】如何取消變量或取消變量賦值?
「unset」命令用於取消變量或取消變量賦值。
語法以下所示:
unset [-fv] [變量或函數名稱]
-f:僅刪除函數
-v:僅刪除變量
應用示例以下:
#!/bin/bash export JAVA_HOME=/usr/local/jdk echo $JAVA_HOME unset JAVA_HOME echo $JAVA_HOME a=100 readonly PI=3.141592653 function func() { echo 'call fun()' } echo 'unset a' unset a func echo 'unset func' unset func echo 'unset PI' unset PI
輸出結果:
注意:unset 刪除不了只讀變量
如上
【22】如何執行算術運算?
有兩種方法來執行算術運算:
1.使用expr命令
# expr 5 + 2
2.用一個美圓符號和方括號($[ 表達式 ])
例如:
test=$[16 + 4]
示例以下:
#!/bin/bash a=2 b=3 result1=$[a + b] result2=`expr $a + $b` echo "result1:$result1" echo "result2:$result2"
輸出結果:
如上。
【23】在shell腳本如何定義函數呢?
函數是擁有名字的代碼塊。
當咱們定義代碼塊,咱們就能夠在咱們的腳本調用函數名字,該塊就會被執行。示例以下所示:
$ diskusage () { df -h ; }
譯註:下面是我給的shell函數語法,原文沒有
[ function ] 函數名 [()]
{
命令;
[return int;]
}
示例以下:
#!/bin/bash function demoFunc() { echo "這是個人第一個shell函數!" } echo "-----函數開始執行-----" demoFunc echo "-----函數執行完畢-----"
輸出結果:
如上。
【24】shell腳本中如何退出?
利用exit退出整個腳本。
示例以下:
#!/bin/bash for i in `seq 1 5` do echo $i if [ $i == 3 ] then echo "exit" exit fi echo $i done echo "end" # 輸出 1 1 2 2 3 exit
如上示例。
【25】shell中如何判斷字符串爲空?
利用test命令,上面有講過。
也能夠以下示例:
#!/bin/bash string= if [ -z "$string" ]; then echo "string is empty" fi if [ -n "$string" ]; then echo "string is not empty" fi
輸出結果:
如上
【26】Shell腳本「$*」和「$@」的聯繫是什麼?
(1)相同點:都是引用全部參數。
(2)不一樣點:只有在雙引號中體現出來。
假設在腳本運行時寫了三個參數 一、二、3,則 " * " 等價於 "1 2 3"(傳遞了一個參數),而 "@" 等價於 "1" "2" "3"(傳遞了三個參數)。
(3)示例
3.1 示例以下(利用vim新建腳本文件difference.sh,輸出以下內容):
#!/bin/bash echo "-- \$* 演示 ---" for value in "$*"; do echo $value done echo "-- \$@ 演示 ---" for value in "$@"; do echo $value done
3.2 輸出結果:
如上
【27】shell 如何實現定時執行任務?
定時器能夠直接利用:/bin/sleep 時間(s)
示例以下:
#!/bin/bash echo "timer invite" count=0 while [ true ]; do # 定時器 1s /bin/sleep 1 count=$[count + 1] echo "invite:$count" done
輸出結果:
如上。
【28】待續
Good Good Study, Day Day Up.
順序 選擇 循環 總結