目錄
- 三、Shell基本編程
- 1、Shell編程介紹
- 2、Shell腳本基本結構
- 3、Shell腳本及運行
- 4、Shell變量及表達式 - 變量類型
- 5、常用的Shell預定義變量
- 6、Shell變量及表達式 - 位置參數
- 7、Shell變量及表達式 –缺省參數
- 8、Shell變量表達式 概述
- 9、Shell腳本流程控制 - 分支語句if
- 10、Shell腳本流程控制 - 分支語句case
- 11、Shell腳本流程控制—循環控制 for
- 12、Shell腳本流程控制—循環控制 while
- 13、Shell腳本流程控制—循環控制 until
- 14、Shell腳本流程控制—函數
- 15、Shell腳本流程控制—數組
- 16、Shell腳本流程控制—序列函數seq
- 17、細節問題1:整數的四則運算
- 18、細節問題2:字符串函數
- 19、細節問題3:浮點數運算
三、Shell基本編程
1、Shell編程介紹
-
Linux體系中的shell編程在實現系統管理與維護、系統使用、用戶環境定製等方面作用突出。
-
使用shell寫的程序通常也稱爲腳本。
-
在用戶主目錄中,在/etc目錄中,隨處可見腳本文件。
-
腳本是由各種變量、表達式、命令等通過一定的邏輯組裝而成的,具有順序解釋執行的特性。
2、Shell腳本基本結構
#!/bin/bash #腳本必須以#!開始
#! 表示:/bin/bash將執行該腳本文件中的程序
# 表示此後的字符串爲註釋
腳本支持:變量、表達式、流程控制、函數、註釋,各種外部命令和程序調用、命令行參數、系統變量等等。
腳本就是將上述各種元素通過一定的邏輯關係進行組裝已完成特定任務的程序。
3、Shell腳本及運行
1、利用vi編輯如下腳本並保持成 first.sh
#!/bin/bash
echo "Hello,welcome to Linux world"
echo "Today is $(date)"
2、設置執行權限
chmod u+x first.sh
3、執行腳本
./first.sh 或 sh first.sh 或 bash first.sh
4、Shell變量及表達式 - 變量類型
-
環境變量(系統工作環境需要的全局變量)
$PATH, $BASH, $HOME, TERM, $PWD
-
自定義變量(僅在腳本中使用局部變量)
語法格式:變量名=變量值 #變量名約定大寫
# 例如 A=10;echo $A SA="hello Linux";echo $SA
-
只讀變量
readonly 變量名
-
導出局部變量
export 變量名 或者 export 變量名=變量值
-
函數中的同名局部變量: local 變量名=變量值
注意問題
- 變量指向一個字符串(含有空格),則變量值必須使用雙引號括起來。例如:
SA=“Hello Linux” - 引用時變量前加$,單引號和雙引號的區別
echo ‘Oh$SA$SA’; echo “Oh$SA$SA” - 清除不需要的變量:unset 變量名
如:unset SA
5、常用的Shell預定義變量
變量名 | 功能 |
---|---|
$# | 位置參數的數量 |
$* | 所有位置參數的內容 |
$? | 命令執行後返回的狀態 |
$$ | 當前進程的進程號 |
$! | 後臺運行的最後一個進程號 |
$0 | 當前執行的進程名 |
6、Shell變量及表達式 - 位置參數
# 一個關於命令位置參數的腳本文件 arg.sh
#!/bin/bash
echo “完整的命令行:$0$*”
echo “程序是:$0”
echo “所有的參數:$*”
echo “參數個數:$#”
echo “第1個參數: $1”
問題:如果參數沒輸入,但程序中需要怎麼辦?
7、Shell變量及表達式 –缺省參數
比如腳本 mycal.sh 5 6 +; mycal.sh 5 6 *
如果沒有輸入 + 或者 * ,我能否默認取爲 + 呢?而不是認爲程序執行出錯呢?
VAR=${參數-word} :有則用參數,否則用word
VAR=${參數=word} :有則用參數, 否則兩個用word
VAR=${參數? word} :有則用參數,否則報錯退出
VAR=${參數+word} :有則用word,否則不做
注意:上述四條經常用在位置參數的使用上。
# 腳本 mycal.sh
#!/bin/bash
LEFT=${1-100} #第一個參數缺省爲100
RIGHT=${2-100} #第二個參數缺省爲100
RE=`expr $LEFT + $RIGHT` #進行相加
echo "$LEFT + $RIGHT = $RE"
8、Shell變量表達式 概述
Shell中的變量表達式主要利用各種測試語句、條件來獲得字符串、文件、數字等所處的狀態。
表達式的操作符主要包括:
-
字符操作符: =, !=, -n , -z
-
數字操作符:-eq, -ne, -ge, -gt, -le, -lt
==, !=, >=, >, <=, <
-
邏輯操作符:!, -a, -o
-
文件操作符:-d, -f, -L,-r, -w, -x, -s, -e, -z,-c, -b,-o
可以使用 test 命令來測試上述各種表達式狀態
test是Shell程序中的一個表達式,通過和Shell提供的if等條件語句相結合可以方便地測試字符串、文件狀態和數字。其語法如下:
test [表達式]
表達式所代表的操作符有字符串操作符、數字操作符、邏輯操作符以及文件操作符。
作用:測試字符串是否相等,長度是否爲零,字符串是否爲NULL。
常用的字符串比較符號如下。
=:比較兩個字符串是否相同,相同則爲“是”。
!=:比較兩個字符串是否相同,不同則爲“是”。
-n:比較字符串的長度是否大於0,如果大於0則爲“是”。
-z:比較字符串的長度是否等於0,如果等於0則爲“是”。
# 在終端命令行輸入
A=abcd; test $A=abcd; echo $?
A=" "; test –z $A; echo $?
test –n $A; echo $?
test –z “$A”; echo $?
B=1234; test $B –eq 1234; echo $?
test $B –gt 1000; echo $?
文件測試表達式通常是爲了測試文件的文件操作邏輯,測試符號如下。
-d:對象存在且爲目錄,則返回值爲“是”。
-f:對象存在且爲文件,則返回值爲“是”。
-L:對象存在且爲符號連接,則返回值爲“是”。
-r:對象存在且可讀,則返回值爲“是”。
-s:對象存在且長度非0,則返回值爲“是”。
-w:對象存在且可寫,則返回值爲“是”。
-x:對象存在且可執行,則返回值爲“是”。
邏輯比較:
test -f /etc/passwd –a –s /etc/passwd;echo $?
test -f /etc/passwd –a –d /etc/passwd;echo $?
test -d /root ; echo $?
test ! –z /etc/passwd; echo $?
9、Shell腳本流程控制 - 分支語句if
- Shell支持的流程控制語句主要有:
- 分支語句:if elif else fi, case … esac
- 循環語句:for, while, until
- 函數定義:function funname()
- 分支語句:if elif else fi, case … esac
if ((條件));then
語句
fi
或者
if [ 條件 ];then
語句
elif[ 條件 ];then
語句
else
語句
fi
#注意:[ 條件 ]中,條件前後必須留有一個空格
# [];then連在一起寫,必須加上分號;
10、Shell腳本流程控制 - 分支語句case
echo -n "Input A="
read A
case $A in
1) echo "select 11";;
2) echo "select 22";;
*) echo "select else";;
esac
#---------
echo -n "Input A="
read A
case $A in
"fuzhou city") echo "select 11";;
"xiamen city") echo "seelct 22";;
*) echo "select else";;
esac
#如果是字符串變量且含有空格,則必須在匹配位置加上引號,如"fuzhou city"
菜單式
OPTIONS="fuzhou xiamen"
select opt in $OPTIONS; do
case "$opt" in
fuzhou) echo "select fuzhou";;
xiamen) echo "select xiamen";;
*) exit ;;
esac
done
#注意:輸入1,opt=fuzhou;輸入2,opt=xiamen。其他則結束
11、Shell腳本流程控制—循環控制 for
for 變量 [ in 數值列表] # for i in 1 2 3 4
do #省略 [ ] 則表示取編所有位置參數
命令
done
#--------
len=10; #指定循環次數
for (( i=0; i< "$len"; i=i+1 ))# 不可以用[]
do
命令
done
#---------
例子:實現1加到100
sum=0
for((i=1;i<101;i=i+1))
do
let sum=sum+$i
done
echo $sum
12、Shell腳本流程控制—循環控制 while
while 條件命令爲真
do
命令
done
#------
while : #無限循環
do
命令
done
#------
例子:實現1加到100
k=1
sum=0
while [ $k -le 100 ] #[ 條件 ]中,條件前後必須留有一個空格
do
let sum=$sum+$k
let k++
done
echo $sum
13、Shell腳本流程控制—循環控制 until
until 條件命令爲假
do
命令
done
#------
until : #無限循環
do
命令
done
#------
例子:實現1加到100
k=1
sum=0
until [ $k –gt 100 ]
do
let sum=$sum+$k
let k++
done
echo $sum
3種方法實現1加到100;4種i++;2種while
14、Shell腳本流程控制—函數
function funname()
{
[return 整數]
}
#------
例1:
function sum()
{
return $(($1+$2))
}
sum 10 20
echo "sum=$?"
#如果沒有return則最後一條命令的返回值就是函數的返回值。
funname()
{
}
#注意:
#[1]函數必須先聲明,才能調用
##[2]函數中的變量同全局變量名相同時,則
#使用 local val=value
#定義局部變量
#[3] 無需(不能)定義參數
#!/bin/bash
gsum=0
function sumn()
{ sum=0
for((i=1;i<=$1;i++))
do
let sum=$sum+$i
done
gsum=$sum
return $sum
}
sumn 10
echo "sum=$?"
#調用注意:
#[1] 直接傳遞參數
# 如 sumn 10
#[2] 函數就是命令,返回值只能通過 $?獲取
# 如 echo "sum=$?"
#[3] 如果需要返回變量值, 則通過全局變量帶回值
# 如 gsum
#!/bin/bash
gsum=0
function sumn()
{ local gsum=0
for((i=1;i<=$1;i++))
do
let gsum=$gsum+$i
done
return $gsum
}
sumn 10
echo "sum=$?"
echo $gsum
#調用注意:
#[1] 全局變量和局部變量的使用區別
# 如gsum
15、Shell腳本流程控制—數組
-
定義:
A=(元素列表,空格隔開)
下標從0開始 如A=(a b c d) -
數組長度
${#A[*]} -
引用第i個元素
KaTeX parse error: Expected '}', got 'EOF' at end of input: {A[i]} -
賦值
A[$i]=value -
以字符串輸出所有元素
echo ${A[*]} -
循環輸出所有元素
A=(a b c 123 ad 21)
Len=${#A[*]}
for((i=0;i<"$Len";i++))
do
echo ${A[$i]}
done
或者
for value in ${A[*]}
do
echo $value
done
16、Shell腳本流程控制—序列函數seq
#生成從1到100的100個元素的數組:
seq 1 100
Len=${#A[*]}
for((i=0;i<"$Len";i++))
do
echo ${A[$i]}
done
17、細節問題1:整數的四則運算
A=10
B=20
C=`expr $A + $B` # C=`expr $A \* $B`
D=$(($A+$B)) # D=$(($A\*$B)) D=$((A+B))
D=$[$A+$B] # D=$[A+B]
let E=A+B # let E=A*B
((F=A+B)) # ((F=A*B))
let A++ # ((A++))
let A+=10 # ((A+=10)) ((A*=10))
#注意:符號(( )) 或 [ ]中的變量可以不寫引用符 $
18、細節問題2:字符串函數
字符串A="HELL:LINUX:WORLD"
#1. 獲得字符串長度
LEN=${#A}
#2. 提取6-10字符
SUB1=${A:5:5}
結果 LINUX
#3. 從第6個字符開始提取
SUB2=${A:5}
結果 LINUX:WORLD
#4. 將符號:替換爲符號/
REP=${A//:/\/}
結果 HELL/LINUX/WORLD
# 將符號:替換爲cc
REP=${A//:/cc}
19、細節問題3:浮點數運算
#主要工具使用bc,(默認爲整數運算,可以通過scale=bits精度小數點尾數,+,-,*,/,^,%)
#1.計算 5-2/3 保留4位小數
A=$(echo "scale=4; 5-2/3"|bc)
#2.
bc –q #進入bc計算器環境
scale=4 #設置小數點4位
5-2/3
quit #退出環境
#3.
bc –q file #執行file文件中的代碼,類C代碼
#prime.txt文件 使用 bc –q prime.txt
define is_prime(n)
{
auto prime,i;
prime=1;
for (i=2;i^2<=n;++i)
{
if (n%i==0){ prime=0; break; }
}
return prime;
}
print "\nPlease enter a positive integer n:\n";
n=read();
print "\n\n"
for (i=2;i<=n;++i)
{
if (is_prime(i)){ print i; print "\n"; }
}
quit;
=4; 5-2/3"|bc)
#2.
bc –q #進入bc計算器環境
scale=4 #設置小數點4位
5-2/3
quit #退出環境
#3.
bc –q file #執行file文件中的代碼,類C代碼
```shell
#prime.txt文件 使用 bc –q prime.txt
define is_prime(n)
{
auto prime,i;
prime=1;
for (i=2;i^2<=n;++i)
{
if (n%i==0){ prime=0; break; }
}
return prime;
}
print "\nPlease enter a positive integer n:\n";
n=read();
print "\n\n"
for (i=2;i<=n;++i)
{
if (is_prime(i)){ print i; print "\n"; }
}
quit;
如果我的文章能夠幫到您,可以順手點個贊!
您的每次 點贊、關注、收藏 都是對我最大的鼓勵!