參考 www.tsnien.idv.tw 翻轉工作室
13-1-2 Shell script 變數
A. 使用者自訂變數
int=5
B. 位置變數 ./ex7_3 Good Luck To You
$1 為第一個位置參數(Good),
$2 為第二個位置參數(Luck);另外,
$# 為參數的數目(4),
$* 為所有參數Good Luck To You
$0 為整體變數,僅表示主程式的命令(ex7_3)
13-2 基本敘述句
13-2-1 輸出敘述 – echo
echo $USER
echo "Good luck to you"
echo Good luck to you
echo "Date: `date`"
tsnien
Good luck to you
Good luck to you
Date: Thu Jul 21 14:10:25 CST 2005
13-2-2 輸入敘述 - Read
echo –n “What is your name =>” //echo –n(-p) 表示沒有換行(Enter 輸入)的功能
read name
echo “Welcome, $name”
What is your name =>Tien-shou
Welcome, Tien-shou
13-2-3 設定位置變數 – Set
set `date` => Thu Jul 21 15:07:17 CST
echo "Time: $4 $5"
echo "Day: $1"
echo "Date: $3 $2 $6"
set 命令將訊息指定到位置變
數內。以執行 date 命令為例,它會出現星期、月、日、時間等訊息,如利用 set 命令指定
位置變數
Time: 15:07:17 CST
Day: Thu
Date: 21 Jul 2005
13-2-4 數學運算 – expr
expr 運算敘述必須利用反向單引號(`)包括起來
echo "Test operator"
echo -n "Please enter first number =>"
read number1
echo -n "Please enter second number =>"
read number2
echo "Calculated results:"
sum=`expr $number1 + $number2` 【等號前後不可以有空格】
echo " Sum = $sum"
dele=`expr $number1 - $number2`
echo " Dele = $dele"
echo " Mult = `expr $number1 \* $number2`" 【\ 抑制 * 特殊功能】星號(*)在 Shell 環境裡是代表 0 個或多個任何字元
echo " Div = `expr $number1 / $number2`"
echo " Rem = `expr $number1 % $number2`"
13-3 條件敘述句
在Script 語言裡,條件敘述大多利用 test 命令,或一對中括號([ ])包起來表示,
有下列三種主要類型:
數值比較
字串比較(或測試)
測試檔案系統 檔案屬性測試敘述
13-3-1 數值比較敘述
test $integer1 –eq $integer2
比較旗號 說 明
-eq 等於(=,若兩數相等則傳回 “真(1)”,否則為 0)
-ne 不定於(!=)
-lt 小於(<)
-le 小於或等於(<=)
-gt 大於(>)
-ge 大於或等於(>=)
test $n1 -eq $n2 = [ $n1 -eq $n2 ] #[ 之後與 ] 之前需空格
sample:
#! /bin/bash
# file_name: ex7_8
echo -n "Enter first number =>"
read n1
echo -n "Enter second number =>"
read n2
if test $n1 -eq $n2
then
echo "Two numbers are eqaul"
else
echo "Not equal"
fi
13-3-2 字串比較敘述
比較運算子 說 明
= 比較兩字串是否相符合,如 str1 = str2。
!= 不符合(即是兩字串內容不相同),如 str1 != str2。
< 小於(依 ASCII 碼比較大小),如 str1 < str2。
> 大於(依 ASCII 碼比較大小),如 str1 > str2。
-n 不是空字串(字串長度大於 0),如 –n str1。
-z 空字串(字串長度為 0),如 –z str1
sample:
#!/bin/bash
# file_name:string_scr
echo "Test string is: Good"
echo -n "Please enter test string =>"
read n1
echo $n1
if [ "$n1" = "Good" ]
then
echo "Corrected input"
else
echo "Not correct input"
fi
13-3-3 檔案屬性測試敘述
test –d file_1
選 項 說 明
-l 該檔案是否屬於鏈結檔案,如是則傳回『真』。
-d 如果是目錄則傳回真。
-e 如果檔案存在則傳回真。
-f 如果檔案存在並且是一般檔案則傳回真。
-g 如果檔案存在並且是特定群組可執行的,則傳回真。
-r 如果檔案存在並且可讀的,則傳回真。
-s 如果檔案存在且存有資料,則傳回真。
-w 如果檔案存在且可寫入資料,則傳回真。
-x 如果檔案存在且可執行,則傳回真。
-nt 比較兩檔案是否較新(修改時間),如 file1 –nt file2。
-ot 比較兩檔是否較舊,如 file1 –ot file2。
#! /bin/bash
# file_name: test_file
if [ ! -e $1 ]; then //如果檔案存在則傳回真。 因為if then放同一行則隔;
echo "file $1 does not exist."
exit 1
fi
if [ -d $1 ]; then //如果是目錄(資料夾)則傳回真。 ----> 檔案則不執行
echo -n "$1 is a directory that you may "
if [ ! -x $1 ]; then //如果檔案存在且可執行,則傳回真
echo -n "not "
fi
echo "search." --------------------------------------------> 檔案則不執行
elif [ -f $1 ]; then 如果檔案存在並且是一般檔案則傳回真。
echo "$1 is a reqular file." yes
else
echo "$1 is a special file."
fi
if [ -O $1 ]; then
echo "you own the file"
else
echo "you do not own the file"
fi
if [ -r $1 ]; then
echo "you have read permission on the file"
fi
if [ -w $1 ]; then
echo "you have write permission on the file"
fi
if [ -x $1 ]; then
echo "you have execute permission on the file"
fi
----------------------------------------
13-4-1 if 選擇結構
【A. if/then/fi 敘述】
if 條件判斷
then
命令敘述區段
fi
if 條件判斷; then
命令敘述區段
fi
更簡潔的格式如下:
if 條件判斷; then; 命令敘述區段; fi
【C. if/else 敘述】
if 條件判斷
then
命令敘述區段1
else
命令敘述區段2
fi
【D. if/elif 敘述】
if 條件判斷
then
命令敘述區段1
…….
elif 條件判斷
then
命令敘述區段2
……
…..
else
命令敘述區段3
……..
fi
---------------------------------------------------------------
補充
exit 0 和 exit 1是做什么的呢 , 我来解释一下:
exit 0 代表正常运行程序并退出程序,
exit 1 代表非正常运行导致退出程序
其实目的就是: 程序退出后, 用户可以 echo $? 来查看是 0 还是 1, 从而达到检测程序是正常结束退出还是产生错误而退出的目的.
如果你用 脚本 a 调用 脚本b ,要在a中判断b是否正常返回,就是根据 exit 0 or 1 来识别。
-------------------------------------------------------------------------
13-4-2 case 選擇結構
#! /bin/bash
# file_name: ex7_15
if [ $# -ne 1 ]; then
echo "Usage: $0 a number"
exit 1 離開
fi
echo $#
echo $1
if [ $1 -gt 0 ] && [ $1 -lt 10 ]
then
case $1 in
1) echo -n "One";echo "一";;
2) echo -n "Two "; echo "二";;
3) echo -n "Three "; echo "三";;
4) echo -n "Four "; echo "四";;
5) echo -n "Five "; echo "五";;
6) echo -n "Six "; echo "六";;
7) echo -n "Seven "; echo "七";;
8) echo -n "Eight "; echo "八";;
9) echo -n "Nine "; echo "九";;
esac
else
echo error input
echo please input 1~9 number,thanks
fi
======================================================
13-5 重複性敘述
for var in List #檔案會一個個,放入var
do
commands
commands
done
sample:
#! /bin/bash
# file_name: ex7_17
for var in `ls` ls是指令用反撇點
do
if [ -f $var ]; then //-f 如果檔案存在並且是一般檔案則傳回真
echo "$var is a reqular file."
fi
done
13-5-2 select 迴圈結構
PS3="Selection =>"
select var in List
do
commands
commands
…….
done
** ctrl + c 結束迴圈 ***
#! /bin/bash
# file_name: ex7_18
PS3="Selection =>"
select var in `ls`
do
if [ $var ]; then
if [ -f $var ]; then #-f 如果檔案存在並且是一般檔案則傳回真
echo "$var is a reqular file."
else
echo "$var not a reqular file."
fi
else
echo "Bad input"
fi
done
13-5-3 while 迴圈結構
while 條件判斷
do
命令區塊
done
sample:
#!/bin/bash
# print 1+2+3, ...+100
count=1
sum=0
max=500
while [ $count -le $max ]; do #-le 小於或等於(<=)
sum=`expr $sum + $count`
count=`expr $count + 1`
echo $sum
echo $count
done
echo "1+2+3+, ...+$max = $sum"
13-5-4 until 迴圈結構
until 敘述正好與 while 迴圈相反,也就是說,當條件不成立時,會執行迴圈區塊
until 條件判斷
do
命令區塊
done
#! /bin/bash
# echo input character until "quit"
echo -n "Input your character (quit) =>"
read string1
until test $string1 = "quit"; do
echo "Your input is $string1"
echo -n "Input again (quit) =>"
read string1
done
echo "You’re Welcome"
13-5-5 break 與 continue 命令
一般程式語言的 for、while 與 until 迴圈,大多會利用 break 與 continue 敘述來中
斷或延續迴圈的執行。同樣的,Shell script 迴圈也擁有這兩個命令的功能,如果是巢狀迴圈
的話,也可在 break 或 continue 敘述後增加一個數字引數(如 break 2 或 continue 2),指
定中斷或延續第幾個迴圈。
13-6 字串處理
13-6-1 字串串接處理
操作範例如下:
$ name=Data => 設定 name 變數內容為字串 Data
$ number=5 => 設定 number 變數內容為字串 5
$ fileName=$name$number => fileName 內容為兩字串串接
$ echo $fileName => 顯示 fileName 變數內容
Data5
$ today=`date +%Y_%m_%d`
$ echo $today
2009_07_21
sample:
#! /bin/bash
# file name: ex7_21
mainName=secure # => 設定 mainName 變數內容
today=`date +%Y_%m_%d` #=> 設定 today 變數內容
fileName=$mainName$today #=> 兩字串串接
touch $fileName #=> 利用 touch 產生空白檔案
ls |grep secure
secure2009_07_21 => 已產生名稱加日期的檔案名稱
sample:
#!/bin/bash
# file name: ex7_22
mainName=andytest
max=5
if test $Count -gt $max #Count> max
then
Count=0
else
Count=`expr $Count + 1`
echo $Count
fi
fileName=$mainName$Count
if test -f $fileName
then
`rm $fileName`
fi
touch $fileName
測試
export Count=3
sh ex7_22.sh
ls andy*
===================================
13-6-2 字串替換處理 – { : }
表 13-1 字串替換處理符號
字串處理符號 功 能
${varName:-word}
若 varName 存在而且不是空值,則傳回該值,否則傳回 word。
功能是測試某個變數是否被定義,若無則回傳預設值。
varName被定義 , 回傳varName
varName未定義 , 回傳word
${varName:=word}
若 varName 存在而且不是空值,則傳回該值,否則將它設定為 word,並回傳。
功能是測試某個變數是否被定義,若無則產生並設定初值 word。
varName被定義 , 回傳varName
varName未定義 , 則varName=word , 且回傳word
${varName:+word}
若 varName 存在而且不是空值,則傳回 word,否則傳回空值(null)。
功能是測試某個變數是否存在。
varName存在 , 回傳 word
varName未定義 , 且回傳回空值(null)
${varName:?message}
若 varName 存在而且不是空值,則回傳該值,否則印出 varName 與 message 訊息,並結束當時的 Shell程式。
功能是測試某個變數是否被定義,以免造成執行上錯誤。
${varName:offset}
${varName:offset:length}
傳回 $varName 變數內由 offset 位置開始(由 0 開始計算),共計 length 長度的字串。
如無指定 length,則傳回 offset 位置以後的字元。
功能是切割字串。
譬如 count=1234567,則 ${count:3},則傳回 4567。如${count:3:2},則傳回 45。
Sample
# file name:ex7_23
mainName=andytest723
max=5
echo "Start Count = $Count" # 顯示目前 Count 變數的內容
now=${Count:=1} #=> 將測試 Count 變數的結果存入 now
echo $Count
if [ -n "$now" ] #=> 測試 now 變數內是否空值 -n have define 給值不等於define,要用export Count=4
then echo $now #=> 如不是空值,則執行下列語句
if [ $now -ge $max ] #=> now 是否超過或等於 5
then
now=0
else
now=`expr $now + 1` #=> now 變數累加一
fi
fileName=$mainName$now # => 製作檔案名稱,如 secure3
if [ -f $fileName ] #=> 該檔案存在則刪除
then
rm $fileName
fi
touch $fileName #=> 產生新的檔案
else
echo "The Count variable is not Exist, no success"
fi
export Count=$now #=> 將新的Count 內容輸出成環境變數
echo "Last Count = $Count" # => 顯示最後的 Count 內容
測試
export Count=3
sh ex7_23.sh
13-6-3 字串比對處理 – { # }
字串比對符號 功 能
${varName#pattern}
若變數(varName)內容的開頭與 pattern 相符,
則刪除相符部分(取最短者),並傳回變數剩餘部份。
${varName##pattern}
若變數(varName)內容的開頭與 pattern 相符,
則刪除相符部分(取最長者),並傳回變數剩餘部份。
${varName%pattern}
若變數(varName)內容的結尾與 pattern 相符,
則刪除相符部分(取最短者),並傳回變數剩餘部份。
${varName%%pattern}
若變數(varName)內容的結尾與 pattern 相符,
則刪除相符部分(取最長者),並傳回變數剩餘部份。
${varName/pattern/string}
${varName//pattern/string}
若變數(varName)內容的開頭與 pattern 相符(varName/),
則由 string 替換該相符部分。
另一種是比對結尾部分(varName//),如果與 pattern 相
符,則由 string 字串替換
-----------------------------
#! /bin/bash
# file name: ex7_24
echo
Name="/first/second/third/full.file.name"
echo "Original name => $Name"
name1=${Name##/*/}
echo "{Name##/*/} From head and match all => $name1"
name1_1=${Name##*/}
echo "{Name##*/} From head and match all => $name1_1"
name2=${Name#/*/}
echo "{Name#/*/} From head and match one => $name2"
name2_2=${Name#*/}
echo "{Name#*/} From head and match one => $name2_2"
name3=${Name%.*}
echo "{Name%.*} From tail and match one => $name3"
name4=${Name%%.*}
echo "{Name%%.*} From tail and match all => $name4"
echo
#test
file="/dir1/dir2/dir3/my.file.txt"
echo file="/dir1/dir2/dir3/my.file.txt"
echo
file1=${file#*/}
echo {file#*/} @@删掉第一个/ 及其左边的字符串: $file1
file2=${file##*/}
echo {file##*/} @@删掉最后一个/ 及其左边的字符串:$file2
file3=${file#*.}
echo {file#*.} @@删掉第一个 . 及其左边的字符串:$file3
file4=${file##*.}
echo {file##*.} @@删掉最后一个. 及其左边的字符串:$file4
file5=${file%/*}
echo {file%/*} @@删掉最后一个/ 及其右边的字符串:$file5
file6=${file%%/*}
echo {file%%/*} @@删掉第一个 / 及其右边的字符串:$file6
file7=${file%.*}
echo {file%.*} @@删掉最后一个. 及其右边的字符串:$file7
file8=${file%%.*}
echo {file%%.*} @@删掉第一个 . 及其右边的字符串:$file8
執行結果
Original name => /first/second/third/full.file.name
{Name##/*/} From head and match all => full.file.name
{Name##*/} From head and match all => full.file.name
{Name#/*/} From head and match one => second/third/full.file.name
{Name#*/} From head and match one => first/second/third/full.file.name
{Name%.*} From tail and match one => /first/second/third/full.file
{Name%%.*} From tail and match all => /first/second/third/full
file=/dir1/dir2/dir3/my.file.txt
{file#*/} @@删掉第一个/ 及其左边的字符串: dir1/dir2/dir3/my.file.txt
{file##*/} @@删掉最后一个/ 及其左边的字符串:my.file.txt
{file#*.} @@删掉第一个 . 及其左边的字符串:file.txt
{file##*.} @@删掉最后一个. 及其左边的字符串:txt
{file%/*} @@删掉最后一个/ 及其右边的字符串:/dir1/dir2/dir3
{file%%/*} @@删掉第一个 / 及其右边的字符串:
{file%.*} @@删掉最后一个. 及其右边的字符串:/dir1/dir2/dir3/my.file
{file%%.*} @@删掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my
參考
https://blog.csdn.net/jiezi2016/article/details/79649382
------
變更 URL 成為檔案目錄位置
#! /bin/bash
# file name: ex7_26
url="Linux.mis.csu.edu.tw"
echo "URL => $url"
name1=${url//'.'/'/'}
echo "Change to file name => $name1
測試
sh ex7_26
URL => Linux.mis.csu.edu.tw
Change to file name => Linux/mis/csu/edu/tw
==============================================================
13-7 函數
(1)
function disp
....
disp //呼叫函數
(2)
funct()
....
funct arg1 arg2 arg3//呼叫函數
13-7-1 區域變數與整體變數
Shell script 是除非有特殊聲明,否則所有的變數都是整體
變數,且與 Shell 環境的特性有關。
Shell script 變數有環境變數、位置變數與自訂變數等三種類型,
其中環境變數是系統產生並適用於任何函數,因此它必定是『整體』變數,
至於位置變數會依照函數(無論子函數或命令程式)被呼叫時,攜帶引數的所在位置而定,
並自動以 $1、$2、$3、…、$n 表示之;函數若再呼叫其他函數,其位置也都使用相同的方式表示,
因此位置變數一定是『區域』變數。
至於自訂變數,除非特別指定為區域變數(local 命令),否則一律為『整體』變數。以
下幾個範例用來說明函數變數的特性。
重點:
1.位置變數一定是『區域』變數
2.自訂變數為『整體』變數 , local 命令指定為區域變數
ex7_28.sh
#! /bin/bash
# 位置變數為區域性, 自訂變數為整體性
funct()
{
echo "Inside function "
echo " funct: $# agrs: $1 $2 $3" # $# $1 $2 $3 為區域變數
var1="in function" # var1 為整體變數 自訂變數,
#除非特別指定為區域變數(local 命令),否則一律為『整體』變數
echo " var1 = $var1"
}
echo "Outside function"
echo " $0: $# args: $1 $2 $3" #
var1="Out function"
echo " var1 = $var1"
echo " "
funct arg1 arg2 arg3 #位置變數一定是『區域』變數。
echo " "
echo "Outside function"
echo " var1 = $var1"
測試
sh ex7_28.sh xx01 xx02 xx03
Outside function
ex7_28.sh: 3 args: xx01 xx02 xx03
var1 = Out function
Inside function
funct: 3 agrs: arg1 arg2 arg3
var1 = in function
Outside function
var1 = in function ***var1為整體變數所以funct內變更為in function
~~~~~~~~~~~~~~~~~~~~~~~~~~
#! /bin/bash
# local 產生區域變數
funct()
{
echo " "
echo "Inside function "
local var1="in function"
echo " var1 = $var1"
}
echo "Outside function"
var1="Out function"
echo " var1 = $var1"
funct
echo " "
echo "Outside function"
echo " var1 = $var1"
函數 funct() 內產生一個 var1 的區域變數,雖然它與主程式的var1 變數
相同名稱,但所佔的記憶體空間不同。
測試
sh ex7_29.sh
Outside function
var1 = Out function
Inside function
var1 = in function ***var1為區域變數
Outside function
var1 = Out function ***所以var1 不會被funct內變更為in function
=================================================
13-7-2 引數傳遞與傳回
ex7_31
#! /bin/bash
# 1+2! + 3! +, ..., +k! = total
fun1()
{
t=$1; sum=1
while [ $t -gt 1 ]; do
sum=`expr $sum \* $t`
t=`expr $t - 1`
done
return $sum
}
echo -n "Please enter a number =>"
read k
sum=1; total=0; i=1
while [ $k -ge $i ]; do
fun1 $i
total=`expr $total + $sum `