shell script 筆記(一)

參考 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 `


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值