標籤:style blog color for 檔案 sp 資料 div on
在指令碼編寫過程中,通常會涉及到參數的輸入。譬如,sh 1.sh 10 20,在執行1.sh這個指令碼中,10即為第一個參數,20即為第二個參數。有時,就會有這個疑惑,即shell指令碼最多可以支援多少個變數呢?疑惑之餘,編寫了如下指令碼,可求出Shell指令碼中可輸入參數的最大個數。
該指令碼涉及到三個小指令碼:1.sh 2.sh 3.sh --在這裡為了方便,指令碼名都是極其簡單的。總的思路是給定一個特定的值n,作為輸入參數的最大個數,然後將1,2,3...n作為指令碼的輸入參數,這通過指令碼2.sh來實現,接著原樣輸出這些參數。如果這些參數全部都能輸出,即代表給定的n是合理的。這通過指令碼3.sh來實現。1.sh實現的功能是通過一個死迴圈,遞增產生n,通過引用2.sh來判定n是否合理。具體可見如下指令碼。
首先我們來看看第一個指令碼1.sh
#!/bin/bashi=0echo 0 > currnumberwhile truedo i=$[$i+1] sh 2.sh $i if [ $? -ne 0 ];then echo $i > maxnumber exit 1 else sed -i ‘1s/$/& ‘$i‘/‘ currnumber fidone
該指令碼主要是提供了一個死迴圈,$i指的是可輸入參數的個數,2.sh用於判定給定參數的個數是否合理,如果合理,則將該數值追加到currnumber這個檔案中,如果不合理,則代表$i-1是shell能接受的最大參數個數。則將該數值輸出到maxnumber檔案中。
currnumber檔案的應用便於檢測指令碼的執行情況。原打算是echo $i >> currnumber,即每一個合理的數值都輸出一行,考慮到檔案有最大行數的限制,在這裡,就將數值輸出到一行。sed -i ‘1s/$/& ‘$i‘/‘ currnumber即實現該功能,將$i的值添加到行尾。
再來看看指令碼2.sh
#!/bin/bashrm -f 1.testtouch 1.testnum=$1echo "#!/bin/bash" > 1.testecho "sh 3.sh" >> 1.testfor ((i=1; i<=$num; i++))do sed -i ‘2s/$/& ‘$i‘/‘ 1.testdonesh 1.test
指令碼2實現的功能是將1,2,3...$i作為3.sh的輸入參數,同樣,sed -i ‘2s/$/& ‘$i‘/‘ 1.test實現的是將1,2,3...n輸出到一行。譬如如果$num=10,則1.test的內容如下所示:
#!/bin/bashsh 3.sh 1 2 3 4 5 6 7 8 9 10
最後我們來看看指令碼3.sh
#!/bin/bashecho 0 > 2.testnum=$#for ((i=1;i<=$num;i++))do sed -i ‘1s/$/& ‘$i‘/‘ 2.test shift 1done
該指令碼實現的是原樣輸出輸入參數,並將該輸入參數輸出到2.test中。同樣,sed -i ‘1s/$/& ‘$i‘/‘ 2.test實現的是追加參數到一行。
總結:
1> sh 1.sh即可求出shell指令碼允許的最大輸入參數個數。
2> 因條件有限,沒有具體求出該值。但我們可跳過1.sh,單純的通過2.sh來判定特定的數值。如,sh 2.sh 100000,經測試100000個輸入參數沒有問題。
3> 該指令碼的亮點是如何將特定的值追加到行尾,這主要通過sed -i ‘1s/$/& ‘$i‘/‘ 2.test來實現,其實1s代表第一行。$代表行尾。
4> 在vim中,0可跳到行首,$可跳到行尾。
5> shift左移輸入參數的位置。預設是左移1位。如shift 3表示原來的$4現在變成$1,原來的$5現在變成$2等等,原來的$1、$2、$3丟棄,$0不移動。
6> 該指令碼存在一個隱患,即文字檔的行有最大的字元限制。但將100000作為輸入參數個數進行測試時,沒有問題,說明文字檔一行還是能容納相當數量的字元。
PS: 在監測2.test的結果時,我們可以用watch cat 2.test,即每兩秒查看一下2.test的內容,但該法有個弊端,資料較多時,無法在一個螢幕中顯示,它只會顯示前面固定的資料,新增的資料不會顯示,但在該例中,我們更加關心的是資料是否增加。如下指令碼可實現該功能:
#!/bin/bashwhile truedo cat 2.test sleep 30done
Shell最多可以輸入多少個參數?