I use: Emacs 26.1 on Windows 10 with tramp with plink/pscp to edit perl scripts on a remote Linux server

The scripts are executable (permissions 755).

When I load and then save them, if short time has passed, the permissions are preserved. However, when I don't save the buffer for somewhat longer time, it corrupts remote file permissions and set them to 666.

Even after switching off the saving of backups problem persists.

How do I fix that? Are there workarounds?

  • I'm assuming your problem is related to auto-saving. You could try disabling it.
    – user12563
    Jan 16 '19 at 18:55
  • Also see C-h v make-backup-files. If the backups are made by renaming, then there's a greater chance of the new file not acquiring the same attributes as the original file, so you might find that backup-by-copying is your answer.
    – phils
    Jan 16 '19 at 23:33
  • Switched off backup files. Will see if the issue arises again. Jan 17 '19 at 10:59

So I got fed up and made this workaround. It just checks the file name of file that has been saved and set permissions based on path.

;; workaround for TRAMP always corrupting file permissions
(defcustom file-mode-alist nil 
  "Automatically set file permissions based on filename.
Each element has the form (REGEXP . MODE)
where REGEXP is a regexp to match against your file name and
      MODE - (integer) file mode (permissions) to set.
Pairs are checked in order of appearance, first one to match is used.
  :type '(alist :key-type regexp :value-type integer)
  :group 'personal)
(setq file-mode-alist '(( "^/pscp:host:.+/lib/.*\\.pm$" . #o644)
                        ( "^/pscp:host:.+/web/.*\\.pl$" . #o755)))

(defun run-regexps (alist str)
  "Iterate over association list alist and try to match regexps with string str"
  (if (null alist) nil
    (let ((a (car alist)))
      (if (string-match (car a) str)
          (cdr a)
        (run-regexps (cdr alist) str)))))
(defun set-remote-permissions ()
  "Set permissions of remote file if filename matched against file-mode-alist"
  (let* ((fn (buffer-file-name (current-buffer)))
         (mode (run-regexps file-mode-alist fn)))
    (when mode (chmod fn mode))))

(add-hook 'after-save-hook 'set-remote-permissions)
  • Additionally to your workaround, I would appreciate if you file a bug report. Together with a short recipe for reproduction, and/or proper traces, it might help to fix this problem. Consult the Tramp manual how to write a bug report. BR, Michael (Tramp maintainer) Jan 21 '19 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.