Tôi đã nhân rộng vấn đề và sử dụng set -x
để xem cả hai lệnh thực sự trông như thế nào. Hóa ra lệnh này
rsync ${RSYNC_OPTIONS} ${SOURCEDIR} ${TARGET}
thực tế là tương đương với điều này
rsync -av --exclude '"done"' ${SOURCEDIR} ${TARGET}
Lưu ý các trích dẫn trong dấu ngoặc kép. Mẫu của bạn không done
; nó là "done"
, như thể thư mục bạn muốn loại trừ có dấu ngoặc kép trong tên thật của nó.
Để khắc phục điều này, bạn có thể khai báo biến mà không cần các trích dẫn rắc rối này:
RSYNC_OPTIONS='-av --exclude done' # poor fix, don't
rsync ${RSYNC_OPTIONS} "${SOURCEDIR}" "${TARGET}"
Nhưng điều này sẽ phản tác dụng nếu mô hình chứa khoảng trắng, vv Một cách tiếp cận khác có thể là với eval
:
RSYNC_OPTIONS='-av --exclude "name with double spaces"'
eval rsync "${RSYNC_OPTIONS}" '"${SOURCEDIR}" "${TARGET}"' # not recommended
eval
sẽ phân tích cú pháp lần thứ hai. Thật khó để sử dụng nó đúng cách và an toàn. Tôi trích dẫn đôi ${RSYNC_OPTIONS}
vì thế "name with double spaces"
không mất không gian gấp đôi. Tôi độc thân trích dẫn "${SOURCEDIR}" "${TARGET}"
, vì vậy các biến này không được mở rộng ngay lập tức (nếu không nội dung của chúng sẽ trải qua quá trình mở rộng). Đây là khó khăn!
Bên cạnh đó, những gì về name "with' quotes
? Để lấy chuỗi chính xác này làm đối số tùy chọn cho rsync --exclude
bạn cần một số trích dẫn mơ hồ và thoát ra trong RSYNC_OPTIONS
tờ khai. Có nhiều lý do để tránh eval
.
Giải pháp thực sự là sử dụng một mảng trong Bash. Mảng lưu ý là không di động.
RSYNC_OPTIONS=(-av --exclude 'name with spaces and $u(h')
rsync "${RSYNC_OPTIONS[@]}" "${SOURCEDIR}" "${TARGET}"
Tôi hiểu lý do tại sao bạn không trích dẫn ${RSYNC_OPTIONS}
trong cách tiếp cận ban đầu của bạn. Bạn nên trích dẫn ${SOURCEDIR}
và (riêng biệt) ${TARGET}
Tuy nhiên. Lệnh trên trích dẫn từng biến đúng.
Hoặc có thể ${SOURCEDIR}
có nghĩa là để xác định nhiều nguồn? Đây sẽ là lý do để không trích dẫn nó, nhưng sau đó nó có thể mang lại những vấn đề tương tự như ${RSYNC_OPTIONS}
. Trong trường hợp này, bạn chắc chắn nên sử dụng một biến mảng ở đây là tốt.
Cũng xem xét tên biến trong chữ thường .