2012-11-18 68 views
2

當我在shell腳本上工作時,我對$ @和「$ @」問題有點不滿。所以,我寫了一個shell腳本來做一些測試。如下所示。

func() 
{ 
    local a="[email protected]" 
    for i in "$a"; do 
     echo "$i ****" 
    done 
} 

func000() 
{ 
    local a="[email protected]" 
    for i in $a; do 
     echo "$i ****" 
    done 
} 

func0() 
{ 
    local [email protected] 
    for i in "$a"; do 
      echo "$i ****" 
    done 
} 

func00() 
{ 
    local [email protected] 
    for i in $a; do 
     echo "$i ****" 
    done 
} 

func1() 
{ 
    for i in "[email protected]"; do 
     echo "$i ****" 
    done 
} 

func2() 
{ 
    for i in [email protected]; do 
     echo "$i ****" 
    done 
} 

func "a b c" 
func a b c 

echo "-----------" 
func0 "a b c" 
func0 a b c 

echo "-----------" 
func00 "a b c" 
func00 a b c 

echo "-----------" 
func000 "a b c" 
func000 a b c 

echo "-----------" 
func1 "a b c" 
func1 a b c 

echo "-----------" 
func2 "a b c" 
func2 a b c 




a b c **** 
a b c **** func 
----------- 
a b c **** func0 
a b c **** 
----------- 
a ****  func00 
b **** 
c **** 
a **** 
b **** 
c **** 
------------ 
a **** func000 
b **** 
c **** 
a **** 
b **** 
c **** 

----------- 
a b c ****  func1 //this has the result that I want. 
a **** 
b **** 
c **** 
----------- 
a ****  func2 
b **** 
c **** 
a **** 
b **** 
c **** 

據我記得,當使用$ @時,我們必須使用雙重quoate,否則會破壞。因此,我知道一些功能肯定不能正常工作。 (我仍然在測試它)

只有func1給了我一個願望結果,然而,事情是我想給變量賦「$ @」。通過審查func0,func000,func0,func00結果,這些都沒有給我正確的東西。所以,我希望有人能幫助我。

另外,我知道sh和bash有區別。如果有人能指出我在哪種情況下可能會突破,我會很高興。謝謝。


更新

我應該說,這個劇本的這個結果,它涉及到的bash或sh或linux的VS SH SH的FreeBSD的版本。

我可能是錯的,如果是的話,只是指出來,非常感謝。在我們沒有數組的情況下,顯然,數組賦值不能工作,替代方法是使用字符串,就像我在func000中所做的那樣,local a =「$ a」;因爲我在$ a;做...

如果使用linux sh 4.5(測試)或bash,請參閱下面的答案。

回答

5

更新,感謝@jordanm,我意識到這是之間的區別不知何故,bash和老sh版本。

這是bash或sh 4.2的解決方案。在老噓,這可能不工作。

33 func3()                   
    34 {                    
    35  local a=("${@}")                
    36                     
    37  for i in "${a[@]}"; do              
    38   echo "$i ****"               
    39  done                   
    40 }   
+0

$ @不是一個變量,它是一個變量數組。 – anishsane

+0

'$ @'不是一個數組('$ {@ [1]}',例如非法)。但是,引用時它的行爲是特殊的和類似數組的:''$ @「'等價於'」$ 1「」$ 2「」$ 3「...」(與「$ *」'相反,相同於「$ 1 $ 2 $ 3 $ 4」')。 – chepner

+0

'local -a a =(「$ @」)',如果你想顯式聲明它爲一個數組。 –

-2

如果你想保留一切報價,你可以試試這個:

test() { 
    local args="[email protected]" 
    for i in `echo "$args"`; do 
     echo "$i ****" 
    done 
} 

test 1 2 3 4 

輸出:

~ $ ./test.sh 
1 **** 
2 **** 
3 **** 
4 **** 
+0

您的測試是不是真的有效,因爲他所有的例子都包含空格的指定參數時,它的例子也會打破。 – jordanm

+0

公平點。我還沒有完全明白這個問題。我的測試確實使用與多個參數相同的空格來處理單引號的參數。 – theon

0

雖然我不是他,我第一次聽說過這樣節省"${@}"的是,當我通過隨機Rich's sh tricks發生。有豐富的提供了許多類似的有益的,最重要的便攜安全方法來解決他的網站上許多共同的問題,但這裏的摘錄,以解決當前的問題:

使用數組

與「強化」工作Bourne shell如Bash,POSIX shell沒有數組類型。然而,由於效率低下,你可以使用純粹的POSIX sh來獲得類似數組的語義。訣竅是你有一個(也是唯一的)數組 - 位置參數「$1」,「$2」等等 - 你可以交換進出這個數組的東西。

更換[email protected]數組的內容很簡單:

set -- foo bar baz boo 

或者,也許更有效:

set -- * 

什麼不明確的是如何保存的[email protected]當前內容,讓你可以它在替換之後返回,以及如何以編程方式生成這些'數組'。嘗試基於以前的把戲此功能使用引號:

save() { 
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 
echo " " 
} 

用法是一樣的東西:

myarray=$(save "[email protected]") 
set -- foo bar baz boo 
eval "set -- $myarray" 
相關問題