Shell-Script

將逗號分隔的變數傳遞給遠端 SSH 會話

  • September 6, 2019

我正在嘗試讀取 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 中,我們會轉義擴展序列,即變數擴展$varas\$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"確保這些變數擴展發生在遠端而不是在本地機器中的變數。

引用自:https://unix.stackexchange.com/questions/539292