我正在嘗試創建一個函數,並相信我找到了一個很好的工作範例,但我不理解背後的所有邏輯。
更具體地說,在「while」行上,有人可以解釋一下測試是什麼以及它的作用嗎? $# 是什麼(# 不是註解字元嗎?),-gt 0 參數來自哪裡?在 while 手冊頁中找不到它。
這是一個範例:
function my_function()
{
while test $# -gt 0
do
$
echo "$1"
shift
done
}
謝謝。
答案1
雖然#
它本身絕對是一條註釋,但$#
包含傳遞給函數的參數數量。
test
是一個程序,可讓您執行各種測試,例如,一個數字是否大於另一個數字(如果您的運算符是-gt
;還有許多其他運算符,請參閱man test
)。如果測試成功(在本例中,如果the number of parameters
IS 大於 0),它將返回成功。
該shift
指令丟棄第一個參數。也減少了$#
整個程式碼可以看作:用一個參數做一些事情(在本例中,將其顯示在螢幕上),然後丟棄它;重複直到沒有剩餘參數。
如果您想查看剩餘的所有參數,對偵錯有用,請檢查以下內容$@
答案2
$#
==> 腳本參數傳遞
test
==>條件評估指令
-gt
==>代表比...更棒
test a -gt b
==> 如果 a 大於 b,則為 true,否則為 false
把它們放在一起:
while test $# -gt 0
==> 當傳遞的參數更多時(之所以改變是因為shift)
讓事情變得棘手的是shift
while 循環體內。
$1
==> 始終代表第一個參數
為了使這一點更具體,假設您正在傳遞參數a
,b
和c
。
$1
==> 代表a
這是你的第一個參數
透過呼叫 now shift
,a
已消失,您的參數清單現在已存在b
,c
因此如果您呼叫$1
now ,b
則它現在是清單中的第一個參數。shift
再次調用您的參數列表現在只是c
,因此$1
是現在c
。再呼叫shift
一次會使參數列表為空,因此 while 條件將不會成功(因為參數列表不再大於 0,因為它的大小現在為零),這將導致 while 循環終止。
使用shift
和引用當前參數有什麼好處$1
?
它使您可以靈活地在腳本中提前不知道腳本中傳遞了多少個參數,並且無論如何都可以在 while 循環中一一迭代它們,始終引用當前參數,因為$1
這意味著腳本的頭部參數列表。通過shift
ing 最終,參數列表將為空,因此使用 while 條件來檢查它是否大於零以便終止而不是無限循環非常重要。
答案3
執行以下腳本以了解變數的含義。將腳本另存為somescript.sh
並使用一些輸入參數呼叫腳本。
#!/bin/bash
echo "I display the total parameters passed to this script from commandline"
echo $#
echo "I display all the parameter values"
echo "Input: $@"
echo "I display the first parameter value"
echo "$1"
shift
echo "After shift: $@"
答案4
如果您能原諒我重複一些答案,我想您可能會發現這很有用。
_fn() { set -- "$@" $(cat)
while ${1+:} false ; do
echo "$1" && [ "$1" = "arg2" ] && echo "$1"
$YOUR_CHK
shift
done
}
echo "arg2" | _fn "arg1"
輸出
arg1
arg2
arg2
它可以處理 cmd 行參數和stdin
.它僅while
在參數數組中保存至少一個參數時運行循環來檢查它們。它確實會丟棄它檢查的每個參數,因此其中一部分$YOUR_CHK
應該是以某種方式保存您認為有價值的資訊。
_fn
如果其內容是腳本主體,或是 shell 函數的形式,則其行為會相同。
_fn
處理stdin
- 在這種情況下,透過將其位置參數 shell數組設定為在命令列上傳遞的所有內容來"arg2" echo
覆蓋|pipe
第一行中的- 或- 並且所有內容都透過 吐出。set
$@
"$@"
cat
$(comand substitution)
while _fn's $1
第一個參數是${set+}
我們取代 shell 的內建函數:true
以滿足while
循環條件。一旦$1
未設定替換失敗,條件就會計算為false
且while
循環中斷。
while
對於循環的每次迭代,如果成功,則_fn() echo
es 的$1
第一個參數&&
(echo
是總是success)[ tests ]
來查看是否$1
等於字串,"arg2"
&&
如果es再次[ test ]
成功。_fn() echo
$1
$YOUR_CHK
是一個空操作 - 它是一個未設定的變量,在 shell 執行任何程式碼之前其計算結果為空。
對於循環的每次迭代,while
我們shift
都會去掉$1
第一個參數。所以在迭代 1 中"$@"
看起來像:
arg1 arg2
但在我們shift
第一次之後,它看起來像:
arg2
在我們shift
上次之後,它看起來像:
因此,這讓我們再次回到${1+:} false
- 因為$1
現在未設置,外殼將不會替換:true
,而只會false
被評估,這會打破while
循環並結束_fn().