有一个脚本很难阅读和调试。
其中某处有如下命令:
sudo chmod -R 777 /$some_var/$another_var
换句话说,它动态创建一个路径,然后以递归方式授予该路径权限。
但是,由于它需要互联网连接并且下载东西,有时这些变量由于错误而为空,并且会执行以下命令:
sudo chmod -R 777 /
这会破坏操作系统。我们需要重新安装它。
我们正在改进脚本,使其更完善、更具弹性。但是,有没有办法阻止用户执行该命令root
?
我的意思是,如果路径是,我希望这个命令不可执行/
,即使对于root
用户来说也是如此:
sudo chmod -R 777 /
答案1
如果你专门询问关于sudo chmod -R 777 /
Ubuntu 的问题,那么你很幸运。GNU 工具有一个选项:--preserve-root
。来自GNU 文档:
/
2.9特殊对待某些命令可能会破坏整个层次结构。[...] 由于此类命令的合法用途很少,因此 GNU
rm
通常拒绝对解析为 的任何目录进行操作/
。如果您确实想尝试删除系统上的所有文件,可以使用 选项--no-preserve-root
,但 选项指定的默认行为--preserve-root
对于大多数目的来说更安全。命令
chgrp
、chmod
和chown
也可以对整个层次结构进行破坏性操作,因此它们也支持这些选项。 [...] 传统和 POSIX 要求这些命令对 进行递归操作/
,因此它们默认为--no-preserve-root
,但使用--preserve-root
选项可以使它们在大多数情况下更安全。为方便起见,您可以--preserve-root
在别名或 shell 函数中指定。请注意,该
--preserve-root
选项还确保即使在取消引用指向的符号链接时也不会修改chgrp
和 。chown
/
/
因此,修改您的脚本以使用:
sudo chmod -R 777 --preserve-root /$some_var/$another_var
请注意,我不赞成使用chmod -R 777
。这是极其罕见的,但chmod -R 777
绝对必要。
您还可以使用set -u
让脚本将未设置的变量视为错误,或者使用${var:?message}
将变量未设置的特定实例视为错误:
$ message="Unset/empty variable not allowed"
$ sudo chmod -R 777 --preserve-root "/${some_var:?$message}/${another_var:?$message}"
bash: some_var: Unset/empty variable not allowed
(默认消息为:parameter null or not set
。)
在 Docker 容器中测试:
root@d9c4e4427d7a:/# chmod -R 777 --preserve-root "/${some_var:?$message}/${another_var:?$message}"
bash: some_var: Unset/empty variable not allowed
root@d9c4e4427d7a:/# some_var=/
root@d9c4e4427d7a:/# another_var=////
root@d9c4e4427d7a:/# chmod -R 777 --preserve-root "/${some_var:?$message}/${another_var:?$message}"
chmod: it is dangerous to operate recursively on '/'
chmod: use --no-preserve-root to override this failsafe
答案2
我们可以阻止 Linux 中 root 执行命令吗?
不。
我们可以阻止 Linux 中的脚本执行命令吗?
是的。不要使用它,自己创建一个。例如,您可以创建一个别名 fpr,chmod
并进行一些有效性检查,然后执行它chmod
。
这很糟糕,就好像:
sudo chmod -R 777 /$some_var/$another_var
sudo
不属于脚本内部。777
总是不好的。750
最多当您有超过 1 个用户时,并且700
应该在单独的机器上优先使用。- 始终必须检查两者是否
$some_var
都$another_var
具有正确的值。健全性检查是脚本的重要组成部分。如果值来自不受信任的来源(例如用户通过命令行执行或编辑配置提供变量),则更是如此。
意思是我希望如果路径为,则此命令不可执行
/
,即使对于 root 用户也是如此:
显而易见的答案是在命令之前添加一个完整性检查来评估变量。您还可以使用别名chmod
来执行自己的命令,该命令对值进行检查。
它必须在脚本里面:检查空是不够的:$some_var="/////////////"
同样糟糕;)
答案3
您可以使用 Bash 的扩展测试括号[[ ... ]]
来预先检查语句if
... 以下将检查是否$path
具有除正斜杠和空格之外的字符以及解析路径本身,并且如果两个参数中的一个或两个都未设置或为空,或者如果两者都是斜杠或全是空格,或者如果解析为...则它将评估为$some_var
false$another_var
像$path
这样/
:
path="/${some_var:-EMPTY}/${another_var:-EMPTY}"
if [[ "$path" = *[!\ /]* && "$(realpath "$path" 2>/dev/null)" != "/" && ! "$path" =~ "EMPTY" ]]
then
# your command using those variables here
# chmod -R 777 "$path"
echo "Directory is not root"
fi
注意:改进解决黑客概率(抚养@grok 的评论...谢谢@grok) 除其他事项外。
答案4
做这个:
# if both of the variables are not empty
if [[ -n "$some_var" && -n "$another_var" ]]
then
# run the chmod command as intended
sudo chmod -R 777 /$some_var/$another_var
else
# only do this if you don't want the script to continue, but to exit with an error message
echo "Error - exiting"
exit
fi
如果任何变量可能包含仅由斜杠(/
字符)组成的字符串,那么您也需要检查这一点。