Shell-Script
將逗號分隔的變數傳遞給遠端 SSH 會話
我正在嘗試讀取 shell 腳本中的逗號分隔變數並將其拆分如下
while [ -z "$variable" ] do printf 'variable: ' read -r variable [ -z "$variable" ] && echo 'Action number cannot be empty; try again.' done for i in $(echo ${variable} | sed "s/,/ /g") do echo "$i" done
它給出如下輸出
abc def
但是,如果我用 SSH 嘗試同樣的事情,它不起作用我正在嘗試如下
while [ -z "$variable" ] do printf 'variable: ' read -r variable [ -z "$variable" ] && echo 'Action number cannot be empty; try again.' done ssh -i my.pem -p 2022 ec2-user@ip-address 'bash -s' << EOF sudo su - << SUEOF echo "input $variable" for i in $(echo ${variable} | sed "s/,/ /g") do echo "$i" done SUEOF EOF
但在 SSH 中,它不列印輸入變數的值,我使用 echo 檢查變數是否傳遞到 SSH 會話,我可以看到變數正在傳遞到 SSH 會話
variable: abc,def input abc,def
請幫我解決問題
這是因為heredoc
$variable
內部的擴展ssh
,是由本地機器上的本地shell而不是在遠端shell中擴展的。通常,如果我們希望擴展發生在遠端 shell 中,我們會轉義擴展序列,即變數擴展$var
as\$var
和命令替換 as\$(..)
而不是。$(..)
因此,在您的
for
循環中,,
您的sed
命令會發生拆分,但您的"$i"
擴展將再次發生在本地 shell 中,這應該發生在遠端 shell 中。由於缺少適當的轉義序列,echo "$i"
將永遠不會在本地 shell 中看到值。
$i
你可以通過標記來繞過\$i
它,它的擴展是遠端發生的。此外,循環for i in $(echo $variable | sed sed "s/,/ /g")
是一種非常脆弱的方式來迭代在 de-limiter 上拆分的列表,
。read
在這種情況下,使用 shell 內置程序ssh -i my.pem -p 2022 ec2-user@ip-address 'bash -s' <<EOF echo "input $variable" IFS="," read -ra split <<<"$variable" for var in "\${split[@]}"; do printf '%s\n' "\$var" done EOF
請注意在數組擴展周圍使用轉義序列,
"\${split[@]}"
以及"\$var"
確保這些變數擴展發生在遠端而不是在本地機器中的變數。