SHELL腳本進階

1、讀取參數shell

$0 程序名稱
$1 第一個參數
$2 第二個參數,依次類推
可使用 basename 來讀取程序名稱:basename $0數組

可使用 dirname 來讀取第一個參數的目錄:dirname $0bash

在使用參數以前應該儘可能測試參數 [ -n "$1" ] 因爲須要將參數做爲字符串所以添加引號函數

特殊的參數變量:
$# 表示參數個數, ${!#} 讀取最後一個參數(因爲不能在大括號中使用$符號,所以使用!代替)
$* 將全部參數做爲一個對象
$@ 將全部參數使用空格分隔的多個對象(所以若一個參數包括空格,應該使用引號)
shift 移位,將$1->$0, $2->$1 ......post

注意:$? 表示最後語句的退出狀態,$$表示進程自身的PID,$!表示SHELL最後運行的進程的pid測試

$()的做用與``相同、${}用於有效地將變量的名稱分隔開來this

while [ -n "$1" ]
do
    case $1 in
    "-a") echo "Found the -a option";;
    "-b") echo "Found the -b option";;
    "-c") echo "Found the -c option";;
   "*")  echo "$1 is not an option";;
    esac
    shift    
done

count=1
cat test1.sh | while read line
do
    echo "Line $count: $line"
    count=$[ $count+1 ]
done

#使用read命令讀取文件,
cat test1.sh | while read line 表示將test1.sh依次讀取,讀取的行保存在line變量之中
 

2、輸入輸出spa

0    STDIN      標準輸入
1    STDOUT     標準輸出
2    STDERR     標準錯誤
command 2>err.log 1>nor.log #重定向標準錯誤與標準輸出
echo "This is an error" >&2 #臨時重定向到標準錯誤
exec 1>nor.log  #永久重定向
exec 0<test1.sh
count=1

while read line
do
    echo "Line #$count: $line"
    count=$[$count+1]
done

#重定向標準輸入的例子

能夠建立本身的文件描述符:日誌

exec 3>test.log 
echo "Test" >&3

重定向文件描述符:code

exec 3>&1
exec 1>nor.log

echo "This should store in the output file"
echo "along with this line"

exec 1>&3

echo "Now things should be back to normal"

exec 3>test.log
.....
exec 3>&- #關閉描述符
#在其中先保存3爲標準輸出,而後重定向標準輸出到文件,完成輸出後,在把標準輸出恢復

列舉文件描述符

/usr/sbin/lsof -p pid

禁止命令輸出

ls -al > /dev/null

3、臨時文件

mktemp zcs.XXXX #按照指定格式在本地目錄建立臨時文件
mktemp -t zcs.XXX #按照指定格式在系統臨時目錄建立臨時文件
mktemp -d #用於建立臨時目錄

4、使用tee命令分流

date | tee tee.log

 

 

函數的使用

 

一、函數定義

複製代碼
function name {
commands
}

name() {
commands
}
複製代碼

#注意,name與大括號之間須要有空格

函數只有在定義以後才能使用,所以在腳本的前面引用後面定義的函數將報錯,另外同名函數將被替換。

二、函數返回值

1)默認返回值:最後一條命令的退出狀態。執行完函數後立刻使用 $? 來提取返回值。

2)使用return語句 

  注意:這兩種方式返回值取值範圍都是 0~255,若爲其餘值將被取摸,所以有很大限制

3)使用函數輸出,以下:

  result=`function`

也就是在函數中使用echo語句進行輸出,將輸出結果賦值給變量,此時能夠輸出任何類型的值,可是注意,全部的echo都將被賦值給變量。若要打印日誌則要注意使用重定向到日誌文件之中。

exec 3>>func.log   #打開描述符3重定向添加到func.log文件之中
......
echo "hah,lala">&3 #將日誌打印到文件之中
複製代碼
function arraydblr {
      local oriarray
      local newarray
      local elements
      local i
      oriarray=(`echo $@`)
      newarray=(`echo $@`)
      elements=$[$#-1]
      echo `date` "ori: ${oriarray[*]},new: ${newarray[*]},elements: $elements" >&3
      for (( i = 0; i <= $elements; i++ ))
      {   
          newarray[$i]=$[${oriarray[$i]} * 2]
      }
      echo `date` ${newarray[*]}>&3
      echo ${newarray[*]}
}
複製代碼

4)函數中使用參數

  向函數傳遞的參數能夠經過 $0 … 相似腳本參數方式讀取

  注意:對於腳本的參數,在函數內部沒法訪問,所以若須要應將其做爲函數參數傳遞。

5)全局變量與局部變量

  默認狀況下,腳本中定義的全部變量都是全局變量,也就是在任何地方均可以訪問

  能夠在腳本的頭部引用腳本末尾定義的全局變量值

  而函數爲了不污染全局變量,能夠在函數內部使用local關鍵字定義變量。

6)數組變量

向函數傳遞數組,(注意:直接給函數傳遞數組變量,只會傳遞數組第一個值)

方法:將數組拆分後傳遞給函數,在函數內部在組裝成數組 

func ${arr[*]}
    
func {
    local arr;
    arr=(`echo 「$@「`)
}

若要從函數中返回數組,只能經過echo的方式,echo ${ayyry[*]},外面使用變量賦值

7)建立庫文件

將函數定義放到單獨的文件之中,而後在使用的地方 經過source或者點命令導入庫文件便可。

還能夠將函數定義到 .bashrc, 或者在其中引用庫文件,這樣全部新shell都引用了

相關文章
相關標籤/搜索