스크립트를 통해 SSH에 공백이 포함된 여러 매개변수 전달

스크립트를 통해 SSH에 공백이 포함된 여러 매개변수 전달

원격 서버에서 여러 파일을 삭제하고 싶습니다. 모든 파일을 하나의 스크립트 배열에 넣은 다음 다른 스크립트를 호출하여 파일을 삭제합니다.

"${b[@]}"의 출력은 다음과 같습니다.

/mnt/DataBK/BackupDropwizardLogs_2015-12-17_04-00-01.tar.gz
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_04-30-01.tar.gz
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_05-00-02.tar.gz

파일을 삭제하는 스크립트는 다음과 같습니다.

#!/bin/bash  
file="$1"  
sshpass -p 'password' ssh [email protected] "echo "$file""

전화를 거는 중에 bash /tmp/1.sh "'${b[@]}'"오류가 발생했습니다.

bash: -c: line 0: unexpected EOF while looking for matching `''  
bash: -c: line 1: syntax error: unexpected end of file

그리고 호출되면 bash /tmp/1.sh "${b[@]}" 파일 변수에만 파일을 할당합니다.
/mnt/DataBK/BackupDropwizardLogs_2015-12-17_04-00-01.tar.gz

위 스크립트에서 공백이 포함된 배열의 값을 파일 변수에 할당하는 방법을 알려주실 수 있나요?

업데이트:: declare -a file=("$@")다른 스크립트에서 설정하여 작동했습니다. 하지만 단지 배열이 아닌 더 많은 매개변수를 보내려면 어떻게 해야 할까요?

답변1

sshpass -p 'password' ssh [email protected] "some_cmd $(printf '%q ' "$@")"
sshpass -p 'password' ssh [email protected] "f() { for i; do some_cmd "$i"; done; }; f $(printf '%q ' some_cmd "$@")"

sshpass 매뉴얼 페이지에 따르면,

sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments

"$@"따라서 다음과 같이 ssh 명령에 모든 것을 전달할 수 있어야 합니다 .

sshpass -p 'password' ssh [email protected] printf '%q\n' "$@"

대상 명령이 이러한 유형의 매개변수 처리를 처리하지 못할 수 있으므로 이 문제를 해결할 수 있습니다.

sshpass -p 'password' 'k(){ for i; do echo $i; done; }; k' "$@"

공백을 사용하여 테스트해 보겠습니다.

set -- 'foo bar' $'lorem\nipsum\td'
# paste that two lines.. Since I don't have sshpass installed, just using ssh.

ssh분명히 망쳤습니다. 가짜 껍질을 연결하고 무슨 일이 일어나는지 봅시다.

#!/bin/bash
# /bin/mysh
# someone:x:1000:1000:FOo,,Bar,:/home/foo:/bin/mysh
printf '%q ' bash "$@"; echo;
exec bash -xv --norc "$@";

잘. 해 보자.

bash -c $'printf %q\\n foo bar lorem\nipsum\td'
printf %q\n foo bar lorem
+ printf %qn foo bar lorem
ipsum   d
+ ipsum d
bash: line 1: ipsum: command not found

분명히 ssh는 이러한 것들을 공백으로 연결합니다. 쿨하지 않아.

사전 이스케이프 처리하면 printf '%q '얻을 수 있습니다.TL;DR답변. 이제 EOF와 실패도 이해할 수 있습니다 -c.

참고: ssh가 버전에 따라 -c를 다르게 수행하는지 확실하지 않습니다. 직접 시도해 볼 수도 있습니다. 최소한 OpenSSH 7.1(ssh.c:955-969).

답변2

질문 제목에 답하려면:

[script]를 통해 공백이 포함된 여러 매개변수를 ssh에 전달하세요.

다음과 같은 따옴표는 사용하지 않는 것이 좋습니다.

  ssh  [email protected]  echo "\"arg   1\"    \"arg   2\""

"arg 1"...첫 번째 및 두 번째 인수로 전송됩니다 "arg 2"(이 경우 원격 시스템의 echo 명령에 대한 출력 결과).

  arg   1 arg   2

참고: echo 명령은 각 매개변수를 출력하며, 매개변수 사이에는 공백이 있습니다. 그러나 단일 인수 내에 포함된 공백은 유지됩니다. 공백이 실제로 논쟁의 일부라는 증거로 이것을 질문 제목에서 요구하는 것입니다.

답변3

첫 번째 스크립트는 다음과 같아야 합니다.

#!/bin/bash
password="mypassword"
filelist=("$@")

for file in "${filelist[@]}";
do 
    sshpass -p '$password' ssh [email protected] "echo \"$file\""
done

for 루프는 각 파일을 명령에 제공합니다.


오류는 다음과 같습니다.

bash: -c: line 0: unexpected EOF while looking for matching `''

스크립트를 호출하는 방식과 관련이 있다고 가정합니다. 다음과 같이 호출해야 합니다(한 줄).

$ ./1.sh "${b[@]}"

관련 정보