问题描述
我想cd
到/var/named
,但它给了我一个权限被拒绝的错误,当我想使用sudo
来做到这一点,我不被允许。这是什么技术原因,是否有可能以其他方式做到这一点?
最佳解决方法
你无法做到这一点的原因很简单,有两点
1
cd
不是程序,而是in-built命令,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
,然后回到正常用户的身份登录。
次佳解决方法
这是因为cd
不是可执行文件,而是改变目录的shell函数。
如果你运行:
type cd
你会得到:
cd is a shell function
您可以使用sudo -s
打开一个交互式shell,然后使用cd
到您想要的目录:
sudo -s
cd /var/named
要返回到正常的shell,只需点击Ctrl
+ D
。
第三种解决方法
值得一提的是,尽管cd
作为shell内置或外部二进制文件的状态,但sudo通过产生一个新的进程来运行指定的命令。
为什么这很重要?由于sudo的基本执行流程与此非常类似:
-
shell生成一个子进程以使用给定的参数运行sudo
-
sudo认证用户并确认他们执行指定命令的权限
-
sudo产生一个子进程来执行指定的命令
-
sudo等待在步骤3中产生的子进程退出
-
sudo退出,返回到shell
-
在步骤1中产生的子进程退出,将用户返回到shell提示符
(这在技术上可能稍微不正确;有一个系统调用实际上用新的系统调用替换了正在运行的进程(这是C库的execve()
)。但为解释此目的,这两者是等效的。)
当你认为当前工作目录是每个进程的一个属性并且被继承但未被提升时,这变得很重要。因此,如果进程A产生一个新的进程B,那么进程B以与进程A相同的工作目录开始。(这就是为什么像ls ./
那样平凡的事情会达到你期望的程度。)但是如果进程B改变它的工作目录,那么除非流程A完全没有注意到这一点,否则A完全不了解这种改变。 (这也就是为什么如果你运行诸如find /
之类的东西并且通过中止half-way,那么你最终并不是在文件系统中的某个看似随机的位置,这是因为当它被中止时,发现恰好在那里看着它。 )
因此,即使sudo cd /somewhere
完全符合罐头上的说法,在sudo
退出时,您会立即将其带回您开始的位置。因此,从用户的角度来看,它变成了no-op。 cd
在执行时调用chdir()
系统库函数来设置新的工作目录,这对用户无帮助。
正如Warren Hill所指出的那样,正确的解决方案(我其实不会称之为解决方法)是使用sudo -i
,它将您放入根shell,您可以随意浏览文件系统并执行任何您想要的命令。不过请注意,当你退出这个shell时,你仍然会从目录层次结构中回到你刚刚开始的地方,这与我上面描述的原因完全相同。
第四种方法
以上所有答案都是正确的;尽管这是一个解决方法
sudo sh -c "cd restricted-dir; some_command"
第五种方法
您也可以暂时更改权限。 chmod 0775路径。确保在必要时将其放回原处。