当您忘记使用 sudo 启动 nano 后,是否可以从 nano 保存为 root ?

当您忘记使用 sudo 启动 nano 后,是否可以从 nano 保存为 root ?

很多时候我用 编辑文件nano,尝试保存并得到权限错误,因为我忘记以 root 身份运行它。有没有一些快速的方法可以让我sudo从编辑器中成为 root 用户,而无需重新打开和重新编辑文件?

答案1

不,您不能授予正在运行的程序启动时没有的权限,这将是称为“权限升级”的安全漏洞。

你可以做两件事:

  1. 保存到 /tmp 或其他位置的临时文件,关闭编辑器,然后将临时文件的内容转储到您正在编辑的文件中。sudo cp $TMPFILE $FILE。请注意,不建议使用mv此方法,因为它可能会导致文件所有权和权限的更改,您只想替换文件内容而不是文件占位符本身。
  2. Ctrl使用+使编辑器后台化z,更改文件所有权或权限,以便可以对其进行写入,然后使用fg返回编辑器并保存。不要忘记修复权限!

一些编辑器实际上可以通过启动具有不同权限的新进程并将数据传递给该进程进行保存来做到这一点。参见示例这个相关问题对于高级编辑器中允许将文件缓冲区写入进程管道的其他解决方案。 Nano 没有能力启动新进程或将数据传递给其他进程,因此它被排除在外。

答案2

我刚刚尝试过nano,最令人惊讶的是,当您开始尝试编辑文件时,它甚至没有警告您该文件是只读的。 (更新:显然nano 2.2确实发出了警告; 2.0 没有。

这是一个执行此操作的(基本)脚本。

它会检查您是否可以编辑该文件,如果不能,它将以 root 身份运行“nano”。

/usr/local/bin/editroot(或者〜/ bin /编辑根

sudo=                       # empty is false, non-empty is true
editor=nano                 # XXX check $EDITOR and $VISUAL

if test -e "$1" && test ! -w "$1"; then
    if test -t 0 && test -t 2; then
        printf "%s is not writable.  Edit with sudo? [y/n] " "$1" 1>&2
        read -n 1
        case $REPLY in
        y|Y)
            sudo=true
            ;;
        n|N)
            sudo=
            ;;
        *)
            printf "\nExpected y or n.  Exiting.\n" 1>&2
            exit 1
            ;;
        esac
    else
        printf "%s is not writable.  Fix the permissions or run \"view\" instead." "$1" 1>&2
        exit 1
    fi
fi

${sudo:+sudo} "$editor" "$1"

我调用了一个命令,view这样如果您知道自己不会进行任何更改,就可以避免出现提示。

/usr/local/bin/视图(或者〜/ bin /视图

editor=nano
readonlyflag=-v

"$editor" $readonlyflag "$1"

已经有一个程序称为viewVi/Vim 的一部分,因此请随意建议一个更好的名称。
(但我认为这个程序的全面实施将使 Vi 变得view多余。)


完整版本

答案3

nano版本 2.9.8(2018)中添加了从外部命令过滤文本的功能。

通过外部命令过滤缓冲区的文本可以通过sudo tee some/path/file.这会将文本保存为some/path/fileroot,前提是您有权访问sudo.

要在编辑器中执行此操作,请按^R^X,即Ctrl+R+ Ctrl+X,然后键入

|sudo tee some/path/file

这将以some/path/fileroot 身份覆盖。

请注意,放弃当前编辑会话并重新打开文件可能更安全,sudo nano some/path/file因为这样您就不必依赖正确键入完整路径名,而可以依赖 shell 的文件名自动完成功能。

答案4

简短回答(但请阅读详细信息):

  1. 在编辑器中打开文件
  2. 转到单独的终端/bash 会话
  3. 备份原文件
  4. 跑步f=forgotsudo.oops; cd ~; [ -e $f ] || mkfifo $f; sudo sh -c "cat $f >> [filename]"; rm $f
  5. 在编辑器中,将文件保存到~/forgotsudo.oops,这会将上下文附加到原始文件中,如下所示sudo

这个过程虽然看起来很复杂,但几乎可以用一句话来处理。

如果您发现自己经常这样做,那么绝对可以编写脚本以实现可重用性。

更多详情:

我希望有经验丰富的人士对此进行验证,因为这是我第一次尝试我认为新颖的解决方案。我真的没想到它会起作用,因为我以前从未见过它被提及。如果由于某种我没有想到的原因,它被证明是一个可怕的想法,我会删除它。

在我看来,它可以包含在脚本(forgotsudo)中并变得更加健壮。

fifo 方法的优点是它几乎可以在任何编辑器中工作,无论编辑器是否可以通过外部命令进行过滤。

长格式解释:

当您尝试保存文件(例如,/etc/abcdef.conf)并意识到您忘记保存文件后sudo,请打开另一个终端(或 tmux 窗口等),然后从 Bash 中:

sudo cp /etc/abcdef.conf /etc/abcdef.conf.bak # back up the original file
cd ~ # or somewhere with write permissions
mkfifo forgotsudo.oops
sudo cat forgotsudo.oops >> /etc/abcdef.conf ; rm forgotsudo.oops

虽然 fifo 是追加~/forgottosudo.oops到真实文件,切换到编辑器并使用编辑器的正常“保存”技术保存缓冲区。例如:

  • 在维姆中,:w! ~/forgotsudo.oops
  • 在 Nano 中,Ctrl+ O,将文件名更改为~/forgotsudo.oops,选择 Y 保存到不同的文件名,然后再次选择 Y 确认“覆盖”。

请注意,在这种情况下,修改后的缓冲区将是附加的到原始文件。然后,您可以退出编辑器,将文件重新编辑为sudo,并删除“重复的”原始文件。当然,这是假设该文件未被某些进程使用,该进程会因重复内容而“阻塞”。

如果它是一个对“坏数据”敏感的文件,当然,您也可以使用单个文件>用新内容覆盖现有文件。但请注意,一旦sudo cat ...执行,原始文件内容将被破坏。如果您因任何原因丢失了编辑器中的缓冲区,该文件将被销毁/清空。一定要做好备份。

旁注:无论是覆盖还是追加,原始文件权限在保存后都保持不变。

相关内容