https://www.steamxo.com/2020/12/25/1612383

Shell script 個人筆記

LUFOR129
6 min readMar 21, 2021

硬體是由Linux內核來驅動的,Linux內核外面是各種應用。shell 是Linux內核與外部應用程式溝通介面,外部程式無法直接操作內核,必須透過shell。如果你看過攻殼機動隊(Ghost in the Shell),草薙素子的靈魂被困在一部機器軀殼內,並以此和外界作互動。

如果把一個硬體與OS系統看成一個人的靈魂,那麼shell 就是靈魂與外界互動的那個軀殼手腳。SHELL是一個命令解釋器,接收應用程式、開發者的命令,調用OS,OS再去調用硬體做計算。

對我來說,學SHELL有幾個好處:

  1. 快速 : 使用簡易編輯器就能撰寫,而且只要Linux幾乎都能執行
  2. 自動化: 整合Linux指令,達到控制整台機器
  3. 很潮: 看到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 : 當前用戶名稱

自定義變數

直接定義即可,但是取值時要在前面加上$字號,要注意幾點與其他語言不同的地方:

  1. 等號左右不可有空白
  2. 在bash中默認所有變數都是字串,無法直接數值運算
  3. 變數如果想要包含空白,用雙引"" 包裹起來
  4. unset可以清除變數
  5. 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了。

其他特殊變數

  1. $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 C
for 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]
done
echo $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 <選項> <參數>

選項:

  1. -p: 指定讀取的提示字
  2. -t: 讀取等待秒
read -t 7 -p "enter your name in 7 seconds " NAME  
echo $NAME

參考資料

  1. https://www.runoob.com/linux/linux-shell.html
  2. http://c.biancheng.net/cpp/view/6994.html

--

--