如果我在根终端su
,那么一切都很好:到处都可以完成。
如果作为普通用户,我尝试使用sudo
来访问/root/
目录,例如,如果我想打开类似的文件,则会出现问题/root/.selected_editor
。
当我达到 /ro 完成时,它仍然可以正常工作并写入/root/
,但随后它停止工作。如果我完成了要手动执行的 Linux Bash 命令的编写,那么此命令就可以正常工作。
root@Xfce:~# cat .se(lected_editor) ---> completion is OK
xxx@Xfce:~$ sudo cat /ro(ot/) ---> completion is still OK
xxx@Xfce:~$ sudo cat /root/.se( ) ---> completion has stopped working
为了看看我是否可以列出里面的内容/root/
,我尝试了一下 sudo ls -a /root/
,结果列表正确。然后我在另一台安装了 Debian 11 的笔记本电脑上尝试,它的表现完全相同。
答案1
文件名的 Tab 补全不是通过要求“sudo cat”提供建议来完成的;它直接由您当前正在输入命令的 shell 完成。而且由于那是尚未在“sudo”下运行,它没有访问 内容的权限/root
,就像 或ls /root
一样echo /root/*
。
永远记住,这sudo
不仅仅是一个特殊的 shell 关键字,告诉它以 root 身份执行操作。这是一个整体单独的程序需要以与ps
或 相同的方式运行。(例如,运行sudo cat something
只会使 shell 运行 /bin/sudo;然后 sudo 获取 root 权限并运行实际的 /bin/cat。)
因此,它的效果仅在命令运行时可见,并且只能影响提供给 sudo 的命令行部分。它看不到“sudo this | that”中管道的其余部分(由 shell 拆分),它无法影响文件重定向(这些重定向由 shell 在“sudo”运行之前完成),也无法影响制表符补全(也由 shell 在启动“sudo”之前完成)。
(尽管对于某些命令,Bash 可能有自定义的“bash-completion”脚本,可能选择例如通过 sudo 运行某些帮助程序来获取文件、服务或进程的列表,但本例中未使用此类脚本。您只处理 Bash 的内置文件名补全。)