Ssh
遠端 SSH 命令有效,但在 bash 腳本中使用時無效
我正在嘗試使用 bash 腳本在遠端伺服器上停止 tomcat。這是功能:
function stop_remote_tomcat () { CURRENT_SERVER=$1 CURRENT_USER=$2 CURRENT_PEM_FILE=$3 COMMAND="ssh -i $CURRENT_PEM_FILE $CURRENT_USER@$CURRENT_SERVER \"/bin/sh sudo /etc/init.d/tomcat stop\"" echo $COMMAND $COMMAND }
然後在 case 語句中呼叫這個函式。
我的問題是,如果我只是複制
echo $COMMAND
語句的輸出並將其作為獨立命令執行,它就可以完美執行。但是當它在腳本中執行時會出現錯誤:sudo /etc/init.d/tomcat stop: No such file or directory
有人可以解釋一下如何在 bash 腳本中實現這一點嗎?
簡短回答:參見BashFAQ #50:我試圖將命令放入變數中,但複雜的情況總是失敗!.
長答案:由於shell解析事物的順序,將命令放入變數中不起作用。具體來說,它會在擴展變數之前解析引號、轉義符等,因此在變數中嵌入引號是行不通的——當它們在命令行中時,它們做任何有用的事情都為時已晚。
可以將命令儲存在數組而不是普通變數中,然後用於
printf %q
引用需要列印的任何部分:[...] COMMAND=(ssh -i $CURRENT_PEM_FILE $CURRENT_USER@$CURRENT_SERVER "/bin/sh sudo /etc/init.d/tomcat stop") printf "%q " "${COMMAND[@]}" echo # Because printf won't add a linefeed "${COMMAND[@]}"
這樣做的問題是,有很多方法可以用空格引用/轉義變數,並且
%q
可能不會選擇你喜歡的一個。另一種選擇是跳過儲存命令,直接“手動”列印:[...] echo "ssh -i $CURRENT_PEM_FILE $CURRENT_USER@$CURRENT_SERVER \"/bin/sh sudo /etc/init.d/tomcat stop\"" ssh -i $CURRENT_PEM_FILE $CURRENT_USER@$CURRENT_SERVER "/bin/sh sudo /etc/init.d/tomcat stop"