RSYNC : Đồng bộ hóa các thư mục / tệp được chọn bằng cách sử dụng rsync
qua mạng gia đình hoặc qua ssh
máy chủ từ xa.
rsync
là tiện ích đồng bộ hóa một chiều có thể xóa các tệp trên mục tiêu, vì vậy hãy đảm bảo sao lưu dữ liệu của bạn trên cả vị trí nguồn và đích và kiểm tra kỹ lưỡng bằng cách sử dụng --dry-run
tùy chọn trước khi thực hiện.
Để đọc về cách định cấu hình đúng .authinfo
tệp, hãy xem https://www.gnu.org/software/emacs/manual/auth.html Một .authinfo
nội dung tệp ví dụ (có thể chứa nhiều mục khác nhau) như sau:
machine mymachine login myloginname password mypassword port myport
Định cấu hình và sử dụng chức năng rsync-remote
để đồng bộ hóa với ssh
máy chủ từ xa. Hoặc, sử dụng chức năng rsync-local
để đồng bộ hóa trên cùng một máy tính hoặc qua mạng gia đình đáng tin cậy.
(require 'auth-source)
;;; EXAMPLE:
;;; (get-auth-info "12.34.567.89" "username")
;;; (get-auth-info "localhost" "root")
(defun get-auth-info (host user &optional port)
(let ((info (nth 0 (auth-source-search
:host host
:user user
:port port
:require '(:user :secret)
:create t))))
(if info
(let* ((port (plist-get info :port))
(secret-maybe (plist-get info :secret))
(secret
(if (functionp secret-maybe)
(funcall secret-maybe)
secret-maybe)))
(list port secret))
nil)))
(defun rsync-filter (proc string)
(cond
((string-match
"^\\([a-zA-Z0-9_\\-\\.]+\\)@\\([a-zA-Z0-9_\\-\\.]+\\)'s password: "
string)
(let* ((user (substring string (match-beginning 1) (match-end 1)))
(host (substring string (match-beginning 2) (match-end 2)))
(password (car (cdr (get-auth-info host user)))))
(process-send-string proc (concat password "\n"))))
((not (or (string-match "files\\.\\.\\.\r" string)
(string-match "files to consider\n" string)))
(with-current-buffer (messages-buffer)
(let ((inhibit-read-only t))
(goto-char (point-max))
(when (not (bolp))
(insert "\n"))
(insert string)
(when (not (bolp))
(insert "\n")))))))
(defun rsync-remote ()
"Use rsync to a remote server via ssh. Back-up your data first!!!"
(interactive)
(let* (
(host "localhost")
(username "root")
(port (or (car (get-auth-info host username))
(number-to-string (read-number "Port: "))))
(source
(let ((dir (expand-file-name (locate-user-emacs-file "elpa/"))))
(if (file-directory-p dir)
dir
(let ((debug-on-quit nil)
(msg (format "`%s` is not a valid directory." dir)))
(signal 'quit `(,msg))))))
(target "/private/var/mobile/elpa/")
(ssh "/usr/bin/ssh")
(rsync "/usr/bin/rsync")
(rsync-include-file "/path/to/include-file.txt")
(rsync-exclude-file "/path/to/exclude-file.txt")
(rsh (concat "--rsh=ssh -p " port " -l " username))
(host+target (concat host ":" target)))
(start-process
"rsync-process"
nil
rsync
"-avr" ;; must specify the `-r` argument when using `--files-from`
"--delete"
;; The paths inside the exclusion file must be relative, NOT absolute.
;;; (concat "--files-from=" rsync-include-file)
;;; (concat "--exclude-from=" rsync-exclude-file)
rsh
source
host+target)
(set-process-filter (get-process "rsync-process") 'rsync-filter)
(set-process-sentinel
(get-process "rsync-process")
(lambda (p e) (when (= 0 (process-exit-status p))
(message "rsync-remote: synchronizing ... done."))))))
(defun rsync-local ()
"Use rsync locally -- e.g., over a trusted home network.
Back-up your data first!!!"
(interactive)
(let (
(rsync-program "/usr/bin/rsync")
(source
(let ((dir (expand-file-name
(file-name-as-directory
(read-directory-name "Source Directory: " nil nil nil nil)))))
(if (file-directory-p dir)
dir
(let ((debug-on-quit nil)
(msg (format "`%s` is not a valid directory." dir)))
(signal 'quit `(,msg))))))
(target (expand-file-name
(file-name-as-directory
(read-directory-name "Target Directory: " nil nil nil nil)))))
(unless (y-or-n-p (format "SOURCE: %s | TARGET: %s" source target))
(let ((debug-on-quit nil))
(signal 'quit `("You have exited the function."))))
(start-process "rsync-process"
nil
rsync-program
"--delete"
"-arzhv"
source
target)
(set-process-filter (get-process "rsync-process") #'rsync-process-filter)
(set-process-sentinel
(get-process "rsync-process")
(lambda (p e)
(when (= 0 (process-exit-status p))
(message "Done!"))))))