【问题标题】:Going root when writing to file/saving file?写入文件/保存文件时进入根目录?
【发布时间】:2023-03-18 10:05:01
【问题描述】:

是否可以在 Emacs 中以非 root 用户身份打开文件(在 root 位置),对其进行编辑,然后在保存时提供密码,以便 Emacs 可以写入文件?还是提供具有不同用户权限的不同缓冲区更好吗?

我知道Tramp,但无法理解。

【问题讨论】:

    标签: emacs root privileges


    【解决方案1】:

    我是这样做的:

    (require 'tramp)
    (defun sudired ()
      (interactive)
      (dired "/sudo::/"))
    

    您将获得一个dired 缓冲区,您在其中拥有root 权限。 您从此处打开的任何后续目录或文件都将使用 root。

    任何其他dired 缓冲区都不会受到影响。

    【讨论】:

    • 优秀。但是有什么方法可以进一步简化流程?从nautilus 复制文件路径,然后从dired 中转到该路径看起来很麻烦。
    • 嗯,dired 是 Emacs 的鹦鹉螺。我不使用任何其他文件管理器:我从 dired 打开所有 pdf 和视频。
    • 创建一个新文件怎么样?我看到 dired-maybe-insert-subdir 但没有看到 file
    • 只是一个普通的C-x C-f,而来自一个 sudo dired 缓冲区就可以了。
    • 黑魔法!除了使用M,我如何设置通过这个创建的文件的权限?因为默认情况下,根目录中的文件是644,而通过它创建的文件是551。这应该是一个新问题吗?
    【解决方案2】:

    更新:我现在使用 sudo-edit(可在 Melpa 或 https://github.com/nflath/sudo-edit 获得),它具有标题警告并且比此功能更强大。


    这是我使用的。您可以以普通用户身份打开一个文件(甚至是尚不存在的文件)或目录,并运行此函数以获取 root 权限。

    (defun find-alternative-file-with-sudo ()
      (interactive)
      (let ((bname (expand-file-name (or buffer-file-name
                                         default-directory)))
            (pt (point)))
        (setq bname (or (file-remote-p bname 'localname)
                        (concat "/sudo::" bname)))
        (cl-flet ((server-buffer-done
                   (buffer &optional for-killing)
                   nil))
          (find-alternate-file bname))
        (goto-char pt)))
    

    我也有这个,它会在缓冲区顶部制作一个大红色横幅,告诉我它已以 root 身份打开。

    (defface find-file-root-header-face
      '((t (:foreground "white" :background "red3")))
      "*Face use to display header-lines for files opened as root.")
    
    (defun find-file-root-header-warning ()
      "*Display a warning in header line of the current buffer.
    This function is suitable to add to `find-file-hook'."
      (when (string-equal
             (file-remote-p (or buffer-file-name default-directory) 'user)
             "root")
        (let* ((warning "WARNING: EDITING FILE AS ROOT!")
               (space (+ 6 (- (window-width) (length warning))))
               (bracket (make-string (/ space 2) ?-))
               (warning (concat bracket warning bracket)))
          (setq header-line-format
                (propertize  warning 'face 'find-file-root-header-face)))))
    
    (add-hook 'find-file-hook 'find-file-root-header-warning)
    (add-hook 'dired-mode-hook 'find-file-root-header-warning)
    

    【讨论】:

      【解决方案3】:

      你不需要任何特殊功能,它是 Emacs 内置的(至少它是 24 版的)。

      以 root 身份打开文件:

      C-x C-f 在 minibuffer 中打开 find-file 对话框。

      然后在文件路径前加上/su::/:

      /su::/path/to/root/file

      系统将提示您输入 root 密码。之后,您可以像 root 一样打开文件。其余的缓冲区将不受影响。但是,如果您从同一缓冲区打开另一个文件,您将自动以 root 身份打开它。

      【讨论】:

      • 最好用/sudo::打开。
      • @jcubic 这取决于您在 sudoers 配置中的内容。在 Ubuntu 之外,不必启用 sudo。
      【解决方案4】:

      我也想有一种打开根文件的方法,所以我想出了这个函数来替换 find-file 中的构建,现在我的 .emacs 中有这个:

      (defun test (&rest args)
        (with-temp-buffer
          (eq (apply 'call-process "test" nil (current-buffer) nil args) 0)))
      
      (defun have-permission (filename)
        ;; only bash expand ~ with home directory
        (let ((expanded (replace-regexp-in-string "~"
                                                  (concat "/home/" (user-real-login-name))
                                                  filename)))
          (if (not (file-exists-p expanded))
              (let ((directory (file-name-directory expanded)))
                (and (test "-r" directory) (test "-x" directory) (test "-w" directory)))
            (and (test "-r" expanded) (test "-w" expanded)))))
      
      
      (defun find-every-file (filename &optional wildcards)
        "Open file use sudo:: if user have no permissions to open the file"
        (interactive
         (find-file-read-args "Find All Files: "
                              (confirm-nonexistent-file-or-buffer)))
        (find-file (if (have-permission filename)
                       filename
                     ;; you can replace that with /su:: if you don't have sudo access
                     (concat "/sudo::" (file-truename filename)))))
      
      (global-set-key (kbd "C-x C-f") 'find-every-file)
      

      如果您尝试在您没有写入权限的目录中打开不存在的文件或不存在的文件,它也可以工作。

      您可以将其与@jpkotta 警告弹出窗口结合使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-10
        • 2019-11-27
        • 1970-01-01
        • 1970-01-01
        • 2010-11-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多