为什么`sudo cd /var/named`不起作用?

我想要进入`/var/named`目录,但是它给了我一个权限被拒绝的错误,并且当我想要使用`sudo`来执行时,我没有被允许。这个问题的技术原因是什么,还有其他的解决方法吗?
5个回答

你不能做这件事的原因很简单,有两个方面。

1

cd不是一个程序,而是一个内置命令,而sudo只适用于程序。

sudo foo表示以root身份运行程序foo。

sudo cd /path无效。

sudo: cd: command not found

因为cd不是一个程序。

2

如果可以使用sudo命令来cd到一个受保护的目录,那么在运行命令sudo cd /var/named后,你将以普通用户身份进入该目录,但普通用户不被允许进入该目录。
这是不可能的。
解决方法:
你可以使用sudo -i来提升自己为超级用户。例如:
sudo -i
cd /var/named 

你现在以root身份登录,可以使用任何命令。完成后输入exit,你将恢复为普通用户身份登录。

1从技术上讲,cd命令既是内置命令又是外部命令。http://unix.stackexchange.com/questions/50058/what-is-the-point-of-the-cd-external-command - kojiro
3@kojiro Ubuntu没有,至少在干净安装的情况下,有/usr/bin/cd这个内置命令。 - Warren Hill
关于第二点:如果你使用 sudo -i(或 sudo su),然后切换到 /var/named 目录,接着执行 su normaluser ... 你可以这样做吗? - Alvin Wong
2@AlvinWong 为什么不试一试并找出答案呢?只需进行以下测试:sudo -i,然后cd到一个不应该进入的目录,在该目录中执行su normal_user,然后输入pwd会显示你在受保护的目录中,但是ls不起作用,会显示"ls: cannot open directory.: permission denied"。 - Warren Hill
解决方法奏效了。 - The Onin
那为什么sudo echo能够工作,它也是一个像cd一样的shell内建命令呢? - Balman Rawat
1sudo echo运行的是/bin/echo而不是echo的shell内置命令。 - Eliah Kagan

这是因为cd不是一个可执行程序,它是一个用于改变目录的shell函数。

如果你运行:

type cd

你会得到:
cd 是一个shell函数
你可以使用sudo -s来打开一个交互式的shell,然后使用cd命令进入你想要的目录:
sudo -s
cd /var/named

要返回到正常的Shell,只需按下Ctrl+D

由于无法使用sudo cd foo,因此您也无法使用sudo type foo,因为它是一个shell内置命令。 - MAChitgarha

所有上面的答案都是正确的;不过这里有一个解决方法。
sudo sh -c "cd restricted-dir; some_command"

4我最喜欢这个解决方案,因为你可以在进行根操作后立即返回非根模式,这样就不会忘记并犯下大错误。 - GlenPeterson
这个命令对我没有起作用。 - john

这也值得记住,尽管“cd”作为一个shell内置命令或外部二进制文件的状态,但是sudo通过生成一个新的进程来运行指定的命令。
为什么这很重要呢?因为sudo的基本执行流程与以下非常相似:
1. Shell生成一个子进程以给sudo传递参数 2. sudo对用户进行身份验证并确认其执行指定命令的权限 3. sudo生成一个子进程来执行指定的命令 4. sudo等待步骤3中生成的子进程退出 5. sudo退出,返回到shell 6. 步骤1中生成的子进程退出,将用户返回到shell提示符
(这可能在技术上略有不准确;实际上有一个系统调用可以用一个新的进程替换正在运行的进程(这就是C库的execve())。然而,对于本说明的目的来说,这两者是等效的。)
这一点在考虑到当前工作目录是每个进程的属性,并且是“继承但不提升”的情况下变得重要。因此,如果进程A生成一个新的进程B,那么进程B将以进程A所在的相同工作目录开始。(这就是为什么像`ls ./`这样平凡的命令会按预期执行。)但是,如果进程B改变了它的工作目录,除非进程A特意寻找,否则A完全不知道这个变化。(反过来说,这就是为什么如果你运行类似于`find /`并在中途中止它,你不会因为find恰好在那个时刻正在查找那里而在文件系统中出现看似随机的位置。)
因此,即使`sudo cd /somewhere`确切地按照字面意思执行,当`sudo`退出时,你会回到起始位置。从用户的角度来看,它实际上成为一个无操作。`cd`在执行时调用`chdir()`系统库函数来设置新的工作目录,这个事实对你作为用户没有帮助。
正如Warren Hill所指出的那样,“适当的解决方案”(实际上我不会称之为一个权宜之计)是使用sudo -i,这将使您进入根 shell,在此您可以自由地浏览文件系统并执行任何命令。但请注意,当您退出此 shell 时,由于我前面描述的相同原因,您仍然会回到起始目录层级中。

这个解释很好,你关于“即使 sudo cd /somewhere 确实按照字面意思执行了,但是当 sudo 退出时,你会回到起始位置。”的部分很有帮助。+1 - harperville

如果你是一个sudo用户,你也可以暂时改变权限。
sudo chmod 0775 路径
或者
sudo chmod +r 文件夹路径
如果需要的话,请确保将其恢复。

2欢迎来到Ask Ubuntu!我建议[编辑]这个答案,以具体细节扩展它,说明如何操作。 (关于什么样的回答被认为是最有价值的,请参阅如何编写好的答案? - David Foerster
我没有使用sudo运行交互式shell的权限,所以这是一个不错的选择。 - Guillaume