和有什麼區別∗and∗一種nd* and@?
考慮以下程式碼:
foo () { echo $* } bar () { echo $@ } foo 1 2 3 4 bar 1 2 3 4
它輸出:
1 2 3 4
1 2 3 4
我正在使用 Ksh88,但我也對其他常見的 shell 感興趣。如果您碰巧知道特定 shell 的任何特殊性,請務必提及它們。
我在 Solaris 的 Ksh 手冊頁中找到了以下內容:
的含義 $ * and $ @ 在不加引號或用作參數分配值或文件名時是相同的。但是,當用作命令參數時, $ * is equivalent to `` $ 1天 $ 2d…’’, where d is the first character of the IFS variable, whereas $ @ 相當於 $ 1 $ 2 ….
我嘗試修改
IFS
變數,但它沒有修改輸出。也許我做錯了什麼?
當它們沒有被引用時,它們是
$*
相同$@
的。您不應該使用其中任何一個,因為一旦您有包含空格或萬用字元的參數,它們就會意外中斷。
"$*"
擴展為一個單詞"$1c$2c..."
。通常c
是一個空格,但它實際上是 的第一個字元IFS
,所以它可以是任何你選擇的字元。我發現它唯一的好用處是:
用逗號連接參數(簡單版)
join1() { typeset IFS=, echo "$*" } join1 a b c # => a,b,c
使用指定的分隔符連接參數(更好的版本)
join2() { typeset IFS=$1 # typeset makes a local variable in ksh (see footnote) shift echo "$*" } join2 + a b c # => a+b+c
"$@"
擴展為單獨的單詞:"$1"
"$2"
...
這幾乎總是你想要的。它將每個位置參數擴展為一個單獨的單詞,這使得它非常適合接受命令行或函式參數,然後將它們傳遞給另一個命令或函式。
"$1"
並且因為它使用雙引號進行擴展,這意味著如果包含空格或星號 (*
) ,則內容不會中斷。讓我們編寫一個名為的腳本
svim
,它vim
使用sudo
. 我們將做三個版本來說明差異。
svim1
#!/bin/sh sudo vim $*
svim2
#!/bin/sh sudo vim "$*"
svim3
#!/bin/sh sudo vim "$@"
對於簡單的情況,所有這些都可以,例如不包含空格的單個文件名:
svim1 foo.txt # == sudo vim foo.txt svim2 foo.txt # == sudo vim "foo.txt" svim2 foo.txt # == sudo vim "foo.txt"
但只有在您有多個參數時才能正常工作
$*
。"$@"
svim1 foo.txt bar.txt # == sudo vim foo.txt bar.txt svim2 foo.txt bar.txt # == sudo vim "foo.txt bar.txt" # one file name! svim3 foo.txt bar.txt # == sudo vim "foo.txt" "bar.txt"
只有當你有包含空格的參數時才能正常工作
"$*"
。"$@"
svim1 "shopping list.txt" # == sudo vim shopping list.txt # two file names! svim2 "shopping list.txt" # == sudo vim "shopping list.txt" svim3 "shopping list.txt" # == sudo vim "shopping list.txt"
所以只會
"$@"
一直正常工作。
typeset
是如何在ksh
(bash
並改為ash
使用local
) 中創建局部變數。這意味著IFS
當函式返回時將恢復到之前的值。IFS
這很重要,因為如果設置為非標準,您之後執行的命令可能無法正常工作。