2016-10-29 92 views
0

我的bash腳本有什麼問題?我試圖在函數中傳遞位置參數。我的最後一個測試 - Test 4的作品,但它的基本命令,我會在命令行上運行,沒有變量替代。shell編程 - 如何在函數內正確傳遞變量

我想打電話給我的功能。有人能告訴我,我的前3次測試的結構是否有效,以及如何糾正?謝謝!

要執行:./myscript.sh dev01 tester

#!/bin/bash 

set +x 

if [[ $# != 2 ]]; then 
    echo "Usage: ./script.sh <ENV> <COMPONENT>" 
    exit 1 
fi 

# Setup VARS 
CREDS="-x foobar -a ec2.local_ipv4" 
ENVIRONMENT="$1" 
ROLES="$2" 

function deploy { 
    knife ssh "$CREDS" "chef_environment:"$ENVIRONMENT" AND roles:*"$ROLES"*" "uname" 
} 

echo "Test 1" 
deploy 

echo "Test 2" 
DEPLOY=$(knife ssh "$CREDS" "chef_environment:"${ENVIRONMENT}" AND roles:*"${ROLES}"*" "uname") 
$DEPLOY 

echo "Test 3" 
knife ssh "$CREDS" "chef_environment:"$ENVIRONMENT" AND roles:*"$ROLES"*" "uname" 

echo "Test 4" 
knife ssh -x foobar -a ec2.local_ipv4 "chef_environment:dev01 AND roles:*tester*" "uname" 

同樣,只有Test 4作品。

+2

考慮習慣使用'deploy(){'而不是'function deploy {' - 以前的語法在任何兼容POSIX的shell中工作,而後者依賴於擴展並且沒有好處來彌補缺乏的便攜性。並考慮mklement0關於在保留空間中回顯的全部大寫變量名的說明。 –

+2

...回到直接問題的主題,順便說一句,你可以考慮[BashFAQ#50](http://mywiki.wooledge.org/BashFAQ/050)額外閱讀(超出適用,有用,在所述答案中給出正確的參考)。 –

回答

2

您的問題與使用函數無關;它與你是如何存儲在一個變量參數,然後再使用該變量的事:

如果你想存儲多個論點(非數組)變量,你不能參考變量雙引號,因爲該值然後作爲單個參數傳遞給目標實用程序。

立即解決辦法是使用$CREDS無引號,但是,使值受到潛在有害shell expansions,所以健壯的方式來傳遞多個參數是使用一個陣列

# Store args. individually as array elements 
CREDS=('-x' 'foobar' '-a' 'ec2.local_ipv4') 

# ... 

# "${CREDS[@]}" passes the elements of the array safely as *individual* 
# arguments. 
knife ssh "${CREDS[@]}" "chef_environment:$ENVIRONMENT AND roles:*$ROLES*" "uname" 

另請注意,我如何直接在雙引號字符串中嵌入$ENVIRONMENT$ROLES變量引用,這也使命令更加健壯。

最後,最好不要使用全大寫的shell變量名稱以便avoid conflicts with environment variables and special shell variables

+1

太棒了!感謝您的清晰和詳細的解釋!我很感激幫助。 – noober