쉼표로 구분된 변수를 원격 SSH 세션에 전달

쉼표로 구분된 변수를 원격 SSH 세션에 전달

쉘 스크립트에서 쉼표로 구분된 변수를 읽고 아래와 같이 분할하려고 합니다.

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


문제 해결을 도와주세요

답변1

$variable이는 heredoc 내부의 확장이 ssh원격 쉘이 아닌 로컬 시스템의 로컬 쉘에 의해 확장되기 때문입니다 . 일반적으로 말하면, 원격 쉘에서 확장이 발생할 것으로 예상되면 확장 시퀀스, 즉 $var대신 변수 확장 \$var및 명령 대체를 이스케이프합니다 \$(..).$(..)

따라서 for루프에서 분할은 명령 ,에서 발생 sed하지만 "$i"확장은 원격 셸에서 발생해야 하는 로컬 셸에서 다시 발생합니다. 왜냐하면부족적절한 이스케이프 시퀀스가 ​​없으면 echo "$i"로컬 쉘에 값이 표시되지 않습니다.

확장이 원격으로 발생 $i하도록 표시하여 이를 우회할 수 있습니다 . \$i또한 루프는 for i in $(echo $variable | sed sed "s/,/ /g")구분 기호에서 목록 분할을 반복하는 매우 취약한 방법입니다 ,. read이 예에서 셸 내장 함수 사용

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"

관련 정보