如果您真的想工作,可以定义一个名为shell的函数,该函数以这种方式运行时将运行新的根shell,否则仅运行常规命令。sudo cd directory
bash
sudo
sudo
在其他的答案提出的,大多数用户不希望打扰这样做,而是将希望:
- 运行
sudo -s
,或者sudo -i
如果您想要登录外壳程序(请记住,一种作用sudo -i
是将您从根目录的主目录中启动),或者sudo bash
您想要强制bash
或能够将选项传递给外壳程序。
- 在新的外壳中运行。
cd directory
- 在新Shell中执行需要作为root采取的所有(其他)操作。
- 完成后,运行
exit
以离开新的外壳。重要的是不要忘记这一点,因为您不想以root用户的身份执行比预期更多的操作!
因此,如果需要,您可以编写一个shell函数(或脚本),该函数在sudo
后跟时执行这些操作的前两个操作cd
,sudo
否则将正常运行。请不要将其用作学习为什么 sudo cd
无法成功的替代方法,因为如果您不了解正在发生的事情,那么您可能会因为被新的shell感到非常困惑(而且您可能不理解任何错误消息)发生)。
这是编写此类Shell函数的一种方法,它还提醒您您在新的Shell中,exit
完成后应退出该外壳。(这提醒很可能是对用户有用的任何技能水平,因为一个不一般习惯于在一个新的shell是当一个运行sudo
没有-s
,-i
或者实际的外壳作为参数的名称。)
# Make sudo treat "sudo cd [DIRECTORY]" as a special case and start a shell.
sudo() {
if [ "$#" -eq 2 ] && [ "$1" = 'cd' ]; then
sudo bash -c '
if cd -- "$2"; then # When cd fails, its own message is enough.
printf "%s: Running %s shell in %s\n" "$0" "$USER" "$2" >&2
printf "%s: Type \"exit\" once you are done!\n" "$0" >&2
exec bash # Replace this bash shell with an interactive one.
fi
' bash _ "$2" # Use $2 as the dir in the intermediate shell, too.
else
command sudo "$@"
fi
}
您可以将其放入您的~/.bashrc
,尽管这是一种很奇怪的使用方式sudo
,您可能只希望偶尔启用它。在这种情况下,最好将其放入自己的文件中。如果您sudo.bash
在主目录中使用这些内容创建了一个名为的文件,则可以通过sudo
运行来使该功能可用-使其代替常规sudo
命令运行. ~/sudo.bash
。这在当前的shell及其子shell中生效,但在其他shell中无效。由于类似.bashrc
的文件不可执行的相同原因,请勿使用标记sudo.bash
可执行文件chmod
。这实际上是一个库,而不是一个独立的Shell脚本。如果你做了作为shell脚本运行它,它将定义函数...但是只能在运行脚本的shell中使用,而不适合作为调用方的您。(当然,您可以为此编写脚本,而这恰恰不是我在这里采用的方法。)
要检查并查看sudo
当前是否被定义为shell函数,并查看其当前定义(如果是),请运行type sudo
。要在定义函数后禁用(即取消定义)该函数,请运行unset -f sudo
。要sudo
即使定义了shell函数也直接手动运行常规命令,请运行command sudo
。但是请注意,你不要有这样做,因为这个sudo
功能实际上做的是自己,只要有多于或少于两个参数传递给它还是第一个参数传递给它的是什么,但cd
。这就是为什么您仍然可以按人们通常使用的方式使用它sudo
。
还要注意,上面显示的shell函数仍然允许您将其他参数传递给它sudo
,但这将阻止它被cd
特殊对待。尽管可以扩展shell函数以支持这种情况,但不支持特别运行。也不是。它创建的外壳与您获得的外壳类似。该代码实际上并未运行,而是使用,因此该选项正常运行。当您传递它时,它实际上会运行两次,并为其传递目录参数(否则为零)。当您运行时,首先它会从您正在运行该函数的shell派生一个单独的bash shell ,并更改目录。如果成功,它将替换sudo -u user cd directory
sudo -i cd directory
sudo -s
sudo -s
sudo bash
-c
bash
cd
sudo cd directory
sudo
该bash外壳带有一个您可以使用的新的交互式外壳。
这是壳函数如何自动“做正确的事”的示例。请注意,它的sudo ls -A /root
行为正常。只有当我尝试使用cd
该目录时,sudo
才会创建一个新的shell,并且明确提醒我正在发生的事情。
ek@Io:~$ sudo ls -A /root
[sudo] password for ek:
.aptitude .bashrc .config .emacs.d .nano .rpmdb
.bash_history .cache .dbus .local .profile
ek@Io:~$ sudo -k # invalidates my current timestamp... like I left for a while
ek@Io:~$ sudo cd /root/.local
[sudo] password for ek:
bash: Running root shell in /root/.local
bash: Type "exit" once you are done!
root@Io:/root/.local#
root@Io:/root/.local#
root@Io:/root/.local# exit
exit
ek@Io:~$
如果您尝试访问sudo cd
一个甚至不能以root用户身份也无法更改的目录,那么您将收到一条错误消息:
ek@Io:~$ sudo cd /nonexistent
[sudo] password for ek:
bash: line 1: cd: /nonexistent: No such file or directory
ek@Io:~$ sudo -k
ek@Io:~$ sudo cd /etc/crontab
[sudo] password for ek:
bash: line 1: cd: /etc/crontab: Not a directory
ek@Io:~$
sudo -k
在上面的示例中,我在两次调用之间使用过它,以表明它在尝试更改目录之前已以root用户身份进行身份验证。但是实际上您不必sudo -k
自己运行。由于shell函数只是实际sudo
命令的一个薄包装,因此缓存凭据和其他常见sudo
行为仍然可以正常进行。
尽管它运行良好并且很整洁,但我承认sudo
用相同名称的功能遮盖真实命令实在是太不可思议了。大多数用户可能只是想执行的步骤sudo -s
,他们自己。但是,如果有人想要这样做,并证明它是可能的,那么它确实存在。cd directory
ls -l
目录本身。