원격 SSH 연결을 통해 rsync를 사용할 때 원격 경로에서 공백을 이스케이프


10

SSH를 사용하여 rsync를 원격 서버에 연결할 때 원격 경로에서 공백 등을 어떻게 탈출합니까? 간단한 백 슬래시는 로컬 bash 프롬프트를위한 ​​공간을 이스케이프하지만 원격 시스템에서는 공간이 경로에서 중단으로 읽혀 지므로 해당 경로의 끝을 표시합니다.

따라서 내가 할 때 rsync -avz /path/to/source/some\ dir/ user@host.tld:/path/to/dest/some\ dir/원격 서버는 원격 서버가 /path/to/dest/some/그 대상을 원격으로 찾을 수 없기 때문에 그것을 읽 습니다. 실제 대상은 "일부"가 아니라 "일부"이기 때문입니다.

동일한 명령을 시도하고 백 슬래시와 공백을 이스케이프하여 로컬 bash 프롬프트를 벗어나 원격 서버의 백 슬래시를 유지하면 (백 슬래시 총계 /path/to/dest/some\\\ dir/:) 실제로 백 슬래시를 원격 서버로 보내지 만 원격 서버는 그런 다음 경로와 공백을 제거 /path/to/dest/some\/하지 않고 경로를 해석합니다 /path/to/dest/some\ dir/.

경로를 따옴표로 감싸려고하면 거의 같은 방식으로 작동하여 공간에서 경로를 효과적으로 차단합니다. 따라서 로컬 bash 프롬프트를 통과하는 것만 작동합니다.

처음에는 "-"(space-hyphen-space) 세그먼트가있는 경로를 사용하고 있었고 원격 서버가 오류 rsync: on remote machine: -: unknown option를 반환 했습니다.이 전체 공백 탈출 노력이 처음부터 시작되었습니다.

따라서 원격 경로에서 공백이나 하이픈과 같은 다른 잘못된 문자를 제거하지 않고도 원격 서버에서 올바르게 작동하려면 어떻게해야합니까?


1
작은 따옴표와 큰 따옴표를 모두 시도하십시오.
jftuga

Javier도 이것에 대해 언급했으며 결국 작동하기 때문에 작업 코드 세그먼트를 그의 답변에 대한 답변으로 붙여 넣었습니다.
퓨전 퓨전

@purefusion Grégory의 답변을 올바른 것으로 표시하십시오. -s필요없이 주소 문제를 수동으로 이중 탈출 적용합니다.
m000

답변:


9

초 기자 시스템 rsync에서 원격 시스템에서 rsync 대상을 호출하는 명령 행을 빌드 한 다음 ssh .... 를 단일 문자열로 사용하여 해당 명령 행을 보냅니다 . 이 단일 문자열은 셸로 전달되어 구문 분석하고 인수로 분할하고 실행 rsync합니다. 이진 안전 컨테이너의 (이미 분할 된, 확장 및 인용되지 않은) 인수를 원격 rsync로 패킹하는 대신 왜 그렇게하는지 전혀 알지 못합니다.

즉, 귀하의 주장은 두 개의 다른 셸로 인용 되고 그에 따라 인용다시 인용 됩니다. 일반적으로 각 인수를 큰 따옴표로 묶은 다음 전체 표현식을 작은 따옴표로 묶습니다. 때로는 충분하지 않거나 동일한 표현을 로컬 및 원격으로 사용하려는 경우 복잡 할 수 있습니다.

이 경우 일반적으로 공백이없고 간단한 모든 ASCII 이름으로 소프트 링크를 설정하고 사용합니다.


8
그리고 승자는 ... 작은 + 큰 따옴표입니다! 어쩌면 이것은 모든 서버에서 다를 수 있으므로 다른 사람들이 다른 사람들에게 도움이되지 않으면 아마도이 답변이 될 것입니다. 다음은 rsync 명령의 원격 쪽에서 사용한 성공적인 코드입니다.'user@host.tld:"/path/to/dest/some\ dir/"'
purefusion

이제 왜이 (내 서버에서)이 작동하지만 다른 옵션 중 하나 (경로를 큰 따옴표로 묶거나 삼중 백 슬래시를 사용하여)하지 않습니까? 중요한 경우 CentOS 5를 실행하고 있습니다.
퓨전 퓨전

그럴 필요는 없습니다. 어떻게 운영하고 있습니까? eval함수를 사용 하거나 함수를 호출 하여 실행하고 있습니까?
Mikel

작은 따옴표와 큰 따옴표를 사용하지 않습니다. 작은 따옴표와 큰 따옴표 및 백 슬래시 이스케이프를 사용하고 있습니다. 3 단계 인용. 이것은 불필요합니다. 다시 묻습니다 : 어떻게 운영하고 있습니까?
Mikel

@Javier "왜 그렇게되는지 모르겠습니다." 아마도 틸드 확장이 작동하도록합니다.
Mikel

2

당신이 말했을 때 당신은 올바른 길을 가고있었습니다 :

동일한 명령을 시도하고 백 슬래시와 공간을 벗어나 로컬 bash 프롬프트를 벗어나 원격 서버의 백 슬래시를 유지하면

가장 쉬운 방법은 다음과 같습니다.

rsync -av dir\ with\ spaces/ server.tld:"dir\ with\ spaces"

이 방법도 잘 작동합니다.

rsync -av dir\ with\ spaces/ server.tld:dir\\\ with\\\ spaces

정확한 결과와 현재보고있는 오류를 게시 할 수 있습니까?

rsync래퍼 스크립트로 양면 을 대체 할 수 있습니까 ?

$ sudo su -
# cd /usr/bin
# mv rsync rsync.real
# cat <<'EOF' >rsync
#!/bin/bash
logfile=/home/yourname/rsync.log
date >> "$logfile"
i=1
for arg in "$@"; do
    echo "arg $i: $arg" >> "$logfile"
    i=$((i+1))
done

rsync.real "$@"
EOF
# chmod +x rsync

그런 다음 rsync를 다시 실행하면 이스케이프 방식이 작동한다는 것을 증명해야합니다.

고객 입장에서:

Sun Feb 13 13:48:12 EST 2011
1: -av
2: dir with spaces/
3: server:dir\ with\ spaces

서버 측:

Sun Feb 13 13:48:13 EST 2011
1: --server
2: -vlogDtpre.iL
3: .
4: dir with spaces

위의 예에서 서버의 네 번째 인수 ( dir with spaces)가 모두 한 줄에 있다는 것은 인용이 올바르게 작동한다는 것을 나타냅니다.

그래도 문제가 해결되지 않으면 rsync -v, 또는 rsync -vv, 또는을 다시 실행하십시오 rsync -vvv. 추가 디버깅 정보를 제공합니다.

다른 두 가지 바보 같은 제안 :

  • 다른 서버는 Linux 서버이며 기본 쉘은 무엇입니까?
    • 어쩌면 파일 이름이 예상과 다르게 확장 될 수 있습니다.
  • -a또는 -r옵션 을 추가하는 것을 잊었 습니까?
    • 나는 당신의 결과를 보지 않고 말할 수 없다

질문의 세부 사항에서 언급했듯이 실제로 두 가지 방법을 모두 시도했습니다. 아마도 그들은 내 서버에서 작동하지 않을 것입니다. 또한 래퍼 스크립트로 혼란스러워하지 않았습니다. 나는 / usr / bin /을 해킹하는 것을 피하려고 노력한다. 어쨌든, 더 구체적인 인용 방법은 실제로 나를 위해 일한 것이기 때문에 아마도 이런 식으로 행동하는 것은 내 서버 일 것이다. OS가 결국 문제의 일부인 경우 다른 서버에있는 사람들이나 CentOS를 실행하지 않는 사람들에게는 여전히 귀하의 제안이 실용적 일 수 있습니다.
퓨전 퓨전

어떻게 작동하게하려면 어떻게 인용 했습니까?
Mikel

중요한 세부 사항을 생략하고 있습니다. 실행중인 실제 명령을 전체적으로 게시하십시오.
Mikel

2

포인트 답변 :

-s (protect args)를 사용하고 경로를 따옴표로 묶으십시오.

rsync -savz user@server:"/my path with spaces/another dir/" "/my destination/"

공백이나 대시와 함께 작동합니다.


감사! 이는 해결 방법이 아닌 적절한 솔루션입니다.
m000

-2

경로를 따옴표로 묶을 수 있습니다.


1
질문의 세부 사항에서 볼 수 있듯이, 나는 이미 이것을 시도했습니다. 그러나 다른 답변은 특정 견적 사용을 제안했으며 실제로 작동했습니다. :)
purefusion 2019

따옴표와 백 슬래시가 모두 필요합니다.
Sridhar Sarnobat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.