Shell程式設計入門
原文地址:https://zhuanlan.zhihu.com/p/102176365
Shell 是什麼?
Shell 是一個命令解釋權,它為使用者提供了一個向 Linux 核心傳送請求以便執行程式介面系統級程式,使用者可以用 Shell 來啟動、掛起、停止甚至是編寫一些程式。
Shell 程式設計快速入門
進入 Linux 終端,編寫一個 Shell 指令碼 hello.sh :
#!/bin/bash
echo 'hello world!'
執行:
# 方法1
sh hello.sh
# 方法2
chmod +x hello.sh
./hello.sh
終端打印出 hello world!
說明:
#!
告訴系統這個指令碼需要什麼直譯器來執行。- 副檔名
.sh
不是強制要求的。 - 方法1 直接執行直譯器,
hello.sh
作為 Shell 直譯器的引數。此時 Shell 指令碼就不需要指定直譯器資訊,第一行可以去掉。 - 方法2 hello.sh 作為可執行程式執行,Shell 指令碼第一行一定要指定直譯器。
Shell 變數
定義
Shell 變數分為系統變數和自定義變數。系統變數有$HOME、$PWD、$USER等,顯示當前 Shell 中所有變數:set
。
變數名可以由字母、數字、下劃線組成,不能以數字開頭。
基本語法
- 定義變數:變數名=變數值,等號兩側不能有空格,變數名一般習慣用大寫。
- 刪除變數:unset 變數名 。
- 宣告靜態變數:readonly 變數名,靜態變數不能unset。
- 使用變數:$變數名
將命令返回值賦給變數(重點)
- A=`ls` 反引號,執行裡面的命令
- A=$(ls) 等價於反引號
Shell 環境變數
定義
基本語法
- export 變數名=變數值,將 Shell 變數輸出為環境變數。
- source 配置檔案路徑,讓修改後的配置資訊立即生效。
- echo $變數名,檢查環境變數是否生效
位置引數變數
基本語法
- $n :$0 代表命令本身、$1-$9 代表第1到9個引數,10以上引數用花括號,如 ${10}。
- $* :命令列中所有引數,且把所有引數看成一個整體。
- $@ :命令列中所有引數,且把每個引數區分對待。
- $# :所有引數個數。
例項:
編寫 Shell 指令碼 positionPara.sh ,輸出命令列輸入的各個引數資訊。
#!/bin/bash
# 輸出各個引數
echo $0 $1 $2
echo $*
echo $@
echo 引數個數=$#
執行:
chmod +x positionPara.sh
./positionPara.sh 10 20
執行結果:
./positionPara.sh 10 20
10 20
10 20
引數個數=2
預定義變數
定義
在賦值定義之前,事先在 Shell 指令碼中直接引用的變數。
基本語法
- $$ :當前程序的 PID 程序號。
- $! :後臺執行的最後一個程序的 PID 程序號。
- $? :最後一次執行的命令的返回狀態,0為執行正確,非0執行失敗。
例項:
編寫 Shell 指令碼 prePara.sh ,輸出命令列輸入的各個引數資訊。
#!/bin/bash
echo 當前的程序號=$$
# &:以後臺的方式執行程式
./hello.sh &
echo 最後一個程序的程序號=$!
echo 最後執行的命令結果=$?
執行結果:
當前的程序號=41752
最後一個程序的程序號=41753
最後執行的命令結果=0 # hello world!
運算子
基本語法
- $((運算式)) 或 $[運算式]
- expr m + n 注意 expr 運算子間要有空格
- expr m - n
- expr \*,/,% 分別代表乘,除,取餘
例項
# 第1種方式 $(())
echo $(((2+3)*4))
# 第2種方式 $[],推薦
echo $[(2+3)*4]
# 使用 expr
TEMP=`expr 2 + 3`
echo `expr $TEMP \* 4`
條件判斷
基本語法
[ condition ] 注意condition前後要有空格。非空返回0,0為 true,否則為 false 。
例項
#!/bin/bash
if [ 'test01' = 'test' ]
then
echo '等於'
fi
# 20是否大於10
if [ 20 -gt 10]
then
echo '大於'
fi
# 是否存在檔案/root/shell/a.txt
if [ -e /root/shell/a.txt ]
then
echo '存在'
fi
if [ 'test02' = 'test02' ] && echo 'hello' || echo 'world'
then
echo '條件滿足,執行後面的語句'
fi
執行結果:
大於
hello
條件滿足,執行後面的語句
流程控制
if 判斷
基本語法
if [ 條件判斷式 ];then
程式
fi
# 或者(推薦)
if [ 條件判斷式 ]
then
程式
elif [ 條件判斷式 ]
then
程式
fi
例項
編寫 Shell 程式:如果輸入的引數大於60,輸出“及格”,否則輸出“不及格”。
#!/bin/bash
if [ $1 -ge 60 ]
then
echo 及格
elif [ $1 -lt 60 ]
then
echo "不及格"
fi
case 分支
基本語法
case $變數名 in
"值1")
如果變數值等於值1,則執行此處程式1
;;
"值2")
如果變數值等於值2,則執行此處程式2
;;
...省略其它分支...
*)
如果變數值不等於以上列出的值,則執行此處程式
;;
esac
例項
當命令列引數為1時輸出“週一”,2時輸出“週二”,其他情況輸出“其它”。
case $1 in
"1")
echo 週一
;;
"2")
echo 週二
;;
*)
echo 其它
;;
esac
for 迴圈
基本語法
# 語法1
for 變數名 in 值1 值2 值3...
do
程式
done
# 語法2
for ((初始值;迴圈控制條件;變數變化))
do
程式
done
例項
- 列印命令列輸入的引數。
#!/bin/bash
# 使用$*
for i in "$*"
do
echo "the arg is $i"
done
echo "=================="
# 使用$@
for j in "$@"
do
echo "the arg is $j"
done
執行結果(回顧一下 $* 和 $@ 的區別):
the arg is 1 2 3
==================
the arg is 1
the arg is 2
the arg is 3
2. 輸出從1加到100的值。
#!/bin/bash
SUM=0
for ((i=1;i<=100;i++))
do
SUM=$[$SUM+$i]
done
echo $SUM
while 迴圈
基本語法
while [ 條件判斷式 ]
do
程式
done
例項
輸出從1加到100的值。
#!/bin/bash
SUM=0
i=0
while [ $i -le $1 ]
do
SUM=$[$SUM+$i]
i=$[$i+1]
done
echo $SUM
讀取控制檯輸入
基本語法
read(選項)(引數)
選項
- -p:指定讀取值時的提示符
- -t:指定讀取值時等待的時間(秒),如果沒有在指定時間內輸入,就不再等待了。
引數
- 變數名:讀取值的變數名
例項
讀取控制檯輸入一個num值。
#!/bin/bash
read -p "請輸入一個數num1=" NUM1
echo "你輸入num1的值是:$NUM1"
read -t 10 -p "請在10秒內輸入一個數num2=" NUM2
echo "你輸入num2的值是:$NUM2"
執行結果:
請輸入一個數num1=10
你輸入num1的值是:10
請在10秒內輸入一個數num2=20
你輸入num2的值是:20
函式
和其它程式語言一樣,Shell 程式設計有系統函式和自定義函式,本文只舉兩個常用系統函式。
系統函式
- basename,刪掉路徑最後一個 / 前的所有部分(包括/),常用於獲取檔名。
基本語法 - basename [pathname] [suffix]
- basename [string] [suffix]
- 如果指定 suffix,也會刪掉pathname或string的字尾部分。
例項
# basename /usr/bin/sort
sort
# basename include/stdio.h
stdio.h
# basename include/stdio.h .h
stdio
- dirname,刪掉路徑最後一個 / 後的所有部分(包括/),常用於獲取檔案路徑。
基本語法 - dirname pathname
- 如果路徑中不含 / ,則返回 '.' (當前路徑)。
例項
# dirname /usr/bin/
/usr
# dirname dir1/str dir2/str
dir1
dir2
# dirname stdio.h
.
自定義函式
基本語法
[ function ] funname[()]
{
Action;
[return int;]
}
# 呼叫
funname 引數1 引數2...
例項
計算輸入兩個引數的和。
#!/bin/bash
function getSum(){
SUM=$[$n1+$n2]
echo "sum=$SUM"
}
read -p "請輸入第一個引數n1:" n1
read -p "請輸入第二個引數n2:" n2
# 呼叫 getSum 函式
getSum $n1 $n2