Thoát khoảng trắng trong đường dẫn từ xa khi sử dụng rsync qua kết nối SSH từ xa


10

Khi sử dụng SSH để kết nối rsync với máy chủ từ xa, làm thế nào để bạn thoát khỏi không gian và như vậy trong đường dẫn từ xa? Dấu gạch chéo ngược đơn giản thoát khỏi không gian cho dấu nhắc bash cục bộ, nhưng trên máy từ xa, không gian đó sau đó được đọc là dấu ngắt trong đường dẫn, do đó đánh dấu sự kết thúc của đường dẫn đó.

Vì vậy, khi tôi làm rsync -avz /path/to/source/some\ dir/ user@host.tld:/path/to/dest/some\ dir/những gì xảy ra là máy chủ từ xa đang đọc như vậy /path/to/dest/some/và vì nó không thể tìm thấy đích đó từ xa, bởi vì đích đến thực sự là "một số thư mục" chứ không chỉ là "một số".

Nếu tôi thử cùng một lệnh và thoát dấu gạch chéo ngược và khoảng trống để vượt qua dấu nhắc bash cục bộ và duy trì dấu gạch chéo ngược cho máy chủ từ xa (tổng cộng ba dấu gạch chéo ngược /path/to/dest/some\\\ dir/:), thì nó thực sự gửi dấu gạch chéo ngược đến máy chủ từ xa, nhưng máy chủ từ xa sau đó diễn giải đường dẫn /path/to/dest/some\/thay vì /path/to/dest/some\ dir/vẫn tước không gian và các ký tự sau nó.

Nếu tôi cố gắng bọc đường dẫn bằng dấu ngoặc kép, nó hành xử khá giống với cách đó, có hiệu quả cắt đường đi ở không gian. Vì vậy, nó cũng chỉ hoạt động để vượt qua dấu nhắc bash cục bộ.

Ban đầu, tôi đang sử dụng một đường dẫn có phân đoạn "-" (dấu cách-dấu cách-không gian) trong đó và máy chủ từ xa đang trả về một lỗi rsync: on remote machine: -: unknown optionbắt đầu từ nỗ lực thoát khỏi không gian này ngay từ đầu.

Vậy tôi phải làm gì để nó hoạt động tốt với máy chủ từ xa, mà không phải xóa khoảng trắng hoặc các ký tự sai khác như dấu gạch nối khỏi đường dẫn từ xa?


1
Hãy thử cả hai dấu ngoặc đơn & kép.
jftuga

Javier cũng đề cập đến điều này và nó đã kết thúc hoạt động, vì vậy tôi đã dán đoạn mã làm việc của mình để trả lời câu trả lời của anh ấy.
tinh khiết

@purefusion Xem xét việc đánh dấu câu trả lời của Grégory là chính xác. Các -svấn đề giải quyết vấn đề mà không cần phải áp dụng thoát kép bằng tay.
m000

Câu trả lời:


9

Trên máy khởi tạo, rsyncxây dựng một dòng lệnh gọi mục tiêu rsync trên máy từ xa, sau đó gửi dòng lệnh đó bằng ssh .... dưới dạng một chuỗi . Chuỗi đơn đó được truyền vào shell để phân tích cú pháp, phân tách thành các đối số và thực thi rsync. Tôi không biết tại sao điều đó được thực hiện, thay vì đóng gói các đối số (đã được chia tách, mở rộng và không trích dẫn) trong một số bộ chứa an toàn nhị phân vào rsync từ xa.

Điều đó có nghĩa là các đối số của bạn sẽ được phân tích cú pháp bởi hai shell khác nhau, trích dẫnyêu cầu tương ứng. Thông thường, tôi gói mỗi đối số bằng dấu ngoặc kép và sau đó toàn bộ biểu thức trên dấu ngoặc đơn. đôi khi nó không đủ hoặc có thể phức tạp nếu bạn muốn sử dụng cùng một biểu thức cục bộ và từ xa.

Trong các trường hợp đó, tôi thường đặt một số liên kết mềm với các tên đơn giản, không có dấu cách, tất cả ASCII và sử dụng tên đó.


8
Và người chiến thắng là ... dấu ngoặc đơn + đôi! Có thể điều này khác nhau trên mỗi máy chủ, vì vậy nếu các câu trả lời khác không hiệu quả với một số người, có lẽ câu trả lời này sẽ có. Đây là mã thành công mà tôi đã sử dụng ở phía xa của lệnh rsync:'user@host.tld:"/path/to/dest/some\ dir/"'
purfusion

Bây giờ đặt ra câu hỏi, tại sao NÀY hoạt động (trên máy chủ của tôi), nhưng không phải là một trong các tùy chọn khác (chỉ gói đường dẫn trong dấu ngoặc kép hoặc sử dụng dấu gạch chéo ba)? Tôi đang chạy CentOS 5 nếu có vấn đề.
tinh khiết

Điều đó không cần thiết. Làm thế nào bạn đang chạy nó? Bạn đang chạy nó bằng cách sử dụng evalhoặc thông qua một cuộc gọi đến một chức năng có lẽ?
Mikel

Bạn không sử dụng dấu ngoặc đơn cộng đôi. Bạn đang sử dụng dấu ngoặc đơn cộng với dấu ngoặc kép cộng với dấu gạch chéo ngược. BA cấp độ trích dẫn. Điều này là không cần thiết. Tôi hỏi lại: Làm thế nào bạn chạy nó ?
Mikel

@Javier "Tôi không biết tại sao nó lại được thực hiện". Có lẽ vì vậy mà mở rộng dấu ngã hoạt động.
Mikel

2

Bạn đã đi đúng hướng khi bạn nói:

Nếu tôi thử cùng một lệnh và thoát dấu gạch chéo ngược và khoảng trắng để vượt qua dấu nhắc bash cục bộ và duy trì dấu gạch chéo ngược cho máy chủ từ xa

Đây là cách tôi thấy dễ nhất để làm điều đó:

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

và cách này cũng hoạt động.

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

Bạn có thể đăng đầu ra chính xác và bất kỳ lỗi nào bạn nhìn thấy?

Bạn có thể thay thế rsynctrên cả hai mặt bằng một tập lệnh bao bọc?

$ 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

Sau đó chạy lại rsync của bạn và nó sẽ chứng minh rằng cách thoát này hoạt động, vd

Phía khách hàng:

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

Phía máy chủ:

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

Trong ví dụ trên, thực tế là đối số thứ 4 trên máy chủ ( dir with spaces) là tất cả trên một dòng nói rằng trích dẫn đang hoạt động chính xác.

Nếu điều này không có ích, hãy thử chạy lại rsync -v, hoặc rsync -vv, hoặc rsync -vvv. Nó sẽ cung cấp cho bạn thêm thông tin gỡ lỗi.

Hai đề nghị ngớ ngẩn khác:

  • máy chủ kia có phải là máy chủ Linux không, và vỏ mặc định của bạn ở đó là gì?
    • có thể nó đang mở rộng tên tệp khác với mong đợi của bạn
  • bạn đã quên để thêm -ahoặc -rtùy chọn?
    • Tôi không thể nói mà không thấy đầu ra của bạn

Như đã đề cập trong chi tiết của câu hỏi, tôi thực sự đã thử cả hai phương pháp đầu tiên của bạn. Có lẽ họ không làm việc trên máy chủ của tôi. Tôi cũng không cảm thấy lộn xộn với các tập lệnh bao bọc. Tôi cố gắng tránh xa việc hack / usr / bin / ... Trong mọi trường hợp, một cách trích dẫn cụ thể khác thực sự hiệu quả với tôi, vì vậy có lẽ máy chủ của tôi hoạt động theo cách này. Đề xuất của bạn chắc chắn vẫn có thể khả thi đối với những người trên các máy chủ khác hoặc những người không chạy CentOS, nếu hệ điều hành là một phần của vấn đề.
tinh khiết

Vì vậy, làm thế nào bạn trích dẫn nó để làm cho nó hoạt động?
Mikel

Bạn đang để lại một số chi tiết quan trọng. Vui lòng gửi lệnh thực tế bạn đang chạy, đầy đủ.
Mikel

2

Câu trả lời điểm:

Sử dụng -s (bảo vệ args) và đặt đường dẫn của bạn trong dấu ngoặc kép:

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

Hoạt động với cả không gian hoặc dấu gạch ngang.


Cảm ơn! Đây là một giải pháp thích hợp, thay vì một cách giải quyết.
m000

-2

Bạn chỉ có thể đặt đường dẫn của bạn trong dấu ngoặc kép.


1
Như bạn có thể đã thấy trong chi tiết của câu hỏi, tôi thực sự đã thử nó. Tuy nhiên, một câu trả lời khác đề nghị sử dụng trích dẫn cụ thể, và điều đó thực sự đã kết thúc. :)
tinh khiết

Bạn cần cả hai dấu ngoặc kép và dấu gạch chéo ngược.
Sridhar Sarnobat
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.