원격 서버에서 여러 파일을 삭제하고 싶습니다. 모든 파일을 하나의 스크립트 배열에 넣은 다음 다른 스크립트를 호출하여 파일을 삭제합니다.
"${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[@]}"