硬體是由Linux內核來驅動的,Linux內核外面是各種應用。shell 是Linux內核與外部應用程式溝通介面,外部程式無法直接操作內核,必須透過shell。如果你看過攻殼機動隊(Ghost in the Shell),草薙素子的靈魂被困在一部機器軀殼內,並以此和外界作互動。
如果把一個硬體與OS系統看成一個人的靈魂,那麼shell 就是靈魂與外界互動的那個軀殼手腳。SHELL是一個命令解釋器,接收應用程式、開發者的命令,調用OS,OS再去調用硬體做計算。
對我來說,學SHELL有幾個好處:
- 快速 : 使用簡易編輯器就能撰寫,而且只要Linux幾乎都能執行
- 自動化: 整合Linux指令,達到控制整台機器
- 很潮: 看到hacker對著黑黑的畫面一陣猛敲,心中自然崇拜了起來
那麼具體shell 解釋會位於/etc/shells
內,我們最常用的會是/bin/sh
和/bin/bash
。bash是sh的母集合,使用sh會去調用bash,一些在bash上成功執行的指令用sh執行會失敗,但同時bash要求的權限也會比較高。你可以echo $SHELL
來查看系統默認shell解析器。
一、 Hello SHELL
基本格式:
#!/bin/bashecho "HELLO SHELL"
第一段#!/bin/bash
是指指定bash為解析器,第二段echo 是印出東西。
執行:
> ./hello.sh
Permission denied> sh hello.sh
HELLO SHELL
有兩種執行方式,執行./hello.sh
是透過系統默認SHELL解釋器(bash)執行,但是bash要求的權限會比較高,所以你可以透過chmod改權限。第二種執行方式是透過調用sh來幫你執行。
> chmod +777 hello.sh
>./hello.sh
HELLO SHELL
二、變數
變數分成三種: 系統變數、自定義變數、外部變數。我們就來一一介紹吧。
系統變數
- $HOME : 當前家目錄
- $PWD : 當前路徑
- $SHELL : 默認解析器
- $USER : 當前用戶名稱
自定義變數
直接定義即可,但是取值時要在前面加上$字號,要注意幾點與其他語言不同的地方:
- 等號左右不可有空白
- 在bash中默認所有變數都是字串,無法直接數值運算
- 變數如果想要包含空白,用雙引"" 包裹起來
- unset可以清除變數
- export 可以把變數提升為全局變數,給其他shell程式使用
a=1
echo $a
echo $b# 清除a
unset a>./hello.sh
1>b="BBB"
>export b
>./hello.sh
1
BBB
在一開始時b變數不存在,在全域變數export b後就能在程式碼中執行b了。
其他特殊變數
- $n
n 為數值,$0為腳本名稱,1~9為第一個到第九個參數,十個參數以上後用大括號${10}
來包覆。
#!/bin/bash
echo "$0,$1,$2">sh hello.sh A BBB C
hello.sh,A,BBB# A BBB分別對應 $1,$2
2. $# (獲取所有參數的個數,用於循環)
3. $*, $@
$* 是代表命令行中所有的參數(看成一個整體)
$@ 是代表命令行中所有的參數(區分對待)
#!/bin/bash
for var in "$*"
do
echo $var
done>./hello.sh A B C
A B Cfor var in "$@"
do
echo $var
done
>./hello.sh A B C
A
B
C
4. $?
判斷上一條命令是否正確執行,正確執行則返回0,非0則代表沒有正確執行了。
>./hello.sh
>echo $?
0>HA HA HA
HA:command not found
>echo $?
127
(非0代表錯誤)
三、運算、比較
原生的bash不支援數學運算,但是我們可以用expr
做運算。同時你也可以用[運算式]
來進行運算。
數字運算
expr +,-,*,/,% (數字之間要有空格、 先乘除後加減)
expr 2 + 3
# 5
expr 2 + 3 \* 5
#17
s=$[(2+3)*4]
echo $s
#20
字串比較
# 23是否大於22
[ 23 -ge 22 ]
echo $?
# 0
# 文件是否存在
[ -e /home/huang/1.txt ]
echo $?
# 1
# 多條線判斷
# [condition1] && [condition2] || [condition3]
# &&前一條執行成功才會執行下一條,||前一條失敗後才會執行下一條
四、流程控制
由if[ 判斷式 ]
組成,注意shell有fi
作為if
的結束。中括與條件後要有空格、if後要有空格
if 語法:
# 注意空格
if [ 條件 ];then
程序1
elif [ 條件 ];then
程序2
fi 或者
if [ 條件 ]
then
程式
fi
例子
if [ $1 -eq 1 ];then
echo "one"
elif [ $1 -eq 2 ];then
echo "two"
fi>./if.sh 1
one
>./if.sh 2
two
>./if.sh 3
case 語法:
case $變量名 in
值1)
程序
;;
值2)
程式
;;
*)
程式
;;
esac
;; 相當於break 、 *) 是默認模式
五、迴圈
由do done所組成
for 語法:
for ((初始值;循環條件;變量變化))
do
程式
done#或是
for 變量 in 值1 值2 值3...
do
程式
done#或是
for var in {min..max..step}
do
程式
done
例子 : 1加到100
#!/bin/bash
s=0
for((i=1;i<=100;i++))
do
s=$[$s+$i]
doneecho $s>./for.sh
5050
while 語法:
while [ 條件 ]
do
程式
done
例子: 1 加到 100
s=0
i=1
while [ $i -le 100 ]
do
s=$[$s + $i]
i=$[$i+1]
done
echo $s>./for.sh
5050
六、讀取
read <選項> <參數>
選項:
- -p: 指定讀取的提示字
- -t: 讀取等待秒
read -t 7 -p "enter your name in 7 seconds " NAME
echo $NAME