여러 SSH를 통해 원격 시스템에서 인수에 공백이 있는 로컬 스크립트를 실행하는 방법은 무엇입니까?

여러 SSH를 통해 원격 시스템에서 인수에 공백이 있는 로컬 스크립트를 실행하는 방법은 무엇입니까?

내 질문과 비슷해요여기, 여러 SSH를 사용하는 경우를 제외하고 다음과 유사합니다.이 질문하지만 인수에 공백이 있습니다 ...

test.sh여러 SSH를 통해 원격 서버에서 로컬 스크립트를 실행하고 싶습니다 . test.sh종종 여러 단어로 구성된 인수를 사용합니다.

테스트.sh:

#!/bin/bash
while getopts b: opt;
do
  case $opt in
    b)
       bval="$OPTARG"
       ;;
  esac
done
echo $bval

call_test.sh

#!/bin/bash
# Do some stuff
PHRASE="multi word arg"
ssh -A user@host1 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"

실행하면 ./call_test.sh올바르게 출력됩니다.

multi word arg

call_test.sh하지만 마지막 줄을 다음과 같이 변경하면 :

ssh -A user@host1 ssh -A user@host2 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"

실행하면 ./call_test.sh다음이 출력됩니다.

multi

기본적으로 단일 SSH에서 다중 SSH로 변경하면 여러 단어로 된 주장이 깨집니다.

여러 ssh 명령이 각 단계에서 여러 단어 인수에 대한 따옴표를 풀고 있다고 생각하지만 이를 방지하는 방법을 잘 모르겠습니다. 여러 SSH에서 실행되는 스크립트에 여러 단어 인수를 성공적으로 전달하는 방법에 대한 아이디어가 있습니까?

편집하다:

나는 믿는다이 답변내가 겪고 있는 문제에 접근합니다.

답변1

2개의 ssh 명령을 통해 전달하는 경우 문자열을 TWICE로 인용하여 이스케이프 처리해야 합니다. 추가 과제를 통해 그렇게 하세요 PHRASE=${PHRASE@Q}.

그러나 ${var@Q}및 (아래 설명) 둘 다 원격 셸에서 지원하지 않을 수 있는 따옴표-이스케이프 형식을 printf %q사용한다는 점에 유의하세요.$'...'.

대신에 test.sh스크립트 의 마지막 줄을 수정한 후 :echo "$bval"echo $bval

PHRASE="multi word     arg"
PHRASE=${PHRASE@Q}
ssh -A user@host1 ssh -A user@host2 "bash -s" -- < ./test.sh -b "${PHRASE@Q}"

multi word     arg

${var@P}이전 버전의 bash에서 지원되지 않는 확장 형식 대신 다음을 사용할 수 있습니다.printf -v var %q:

PHRASE="multi word     arg"
printf -v PHRASE %q "$PHRASE"
printf -v PHRASE %q "$PHRASE"
ssh -A user@host1 ssh -A user@host2 "bash -s" -- < ./test.sh -b "$PHRASE"

또한 비효율적인 stdin을 통해 스크립트를 제공하는 대신(bash는 stdin에서 스크립트를 읽을 때 각 바이트에 대해 읽기 시스템 호출을 수행합니다) 전체 스크립트와 해당 인수를 변수에 넣을 수 있습니다.

printf -v cmd 'bash -c %q bash -b %q' "$(cat test.sh)" 'multi word   wahterve'
printf -v cmd %q "$cmd"
ssh localhost ssh localhost "$cmd"

multi word   wahterve

관련 정보