【发布时间】:2020-07-08 03:02:57
【问题描述】:
我使用 Debian Buster 在 Raspberry Pi 上为嵌入式应用程序创建了一个只读系统。 apache2 服务器正在其上运行,并带有我需要的应用程序的配置网页。 我需要以读写模式重新挂载文件系统以编辑系统文件,并在调用 shell 函数的 php 页面上添加了一个工具箱按钮。
这是特定按钮的代码:
<p><label>Remount Read-Write</label>
<button type="submit" name="rw">Remount</button>
</p>
<p><label>Remount Read-Only</label>
<button type="submit" name="ro">Remount</button>
</p>
<?php
if(isset($_POST['rw'])){
$cmd='sudo /home/pi/mount.sh --rw';
shell_exec($cmd);
}
else if(isset($_POST['ro'])){
$cmd='sudo /home/pi/mount.sh --ro';
shell_exec($cmd);
}
?>
在 shell 脚本中,有一行代码用于在 rw 模式下使用选项“--rw”挂载根路径, 特别是命令是:
/bin/mount -o remount,rw /
与 '--ro' 相同,但使用 ro 选项。
我还在 /etc/sudoers.d 中添加了一个 suoders 文件,其中包含以下行:
www-data ALL=(ALL) NOPASSWD: /home/pi/mount.sh
问题是命令执行没有错误,但文件系统没有重新挂载。 如果我像这样通过 shell 执行命令:
p@localhost# sudo mount -o remount,rw /
php shell_exec 开始工作,我可以通过 php 页面挂载和重新挂载。
我不明白为什么 php 页面只有在我通过 shell 重新挂载后才开始工作。
编辑
这是被调用的脚本:
#!/bin/bash
# Remount filesystem
# Options:
# --rw: remount read-write filesystem
# --ro: remount read-only filesystem
if [ "$#" == 1 ]; then
if [ $1 == "--rw" ]; then
sudo /bin/mount -o remount,rw /
echo -e "Filesystem remounted in read-write mode"
elif [ $1 == "--ro" ]; then
sudo /bin/mount -o remount,ro /
echo -e "Filesystem remounted in read-only mode"
elif [ $1 == "--help" ] || [ $1 == "-h" ]; then
echo -e "Remount Filesystem tool"
echo "use remount.sh [OPTION]"
echo ""
echo -e "--rw \tremount read-write filesystem"
echo -e "--ro \tremount read-only Filesystem"
echo -e "--help (-h) \tprint help"
else
echo "use -h or --help to see options"
fi
else
echo "use -h or --help to see options"
fi
已解决
我找到了问题的解决方案。
主要问题是由于 apache2.service 上的 systemcl 选项。
默认情况下,该服务具有PrivateTemp=true 选项。
改在PrivateTemp=false 解决了这个问题。
据我了解,PrivateTemp 设置为 true 用于创建不共享的文件系统命名空间。默认情况下,apache2 为临时文件的安全访问创建一个单独的命名空间。
我查看了几个链接来解决这个问题:
(U)Mounting through "exec" with "sudo". The user is a "sudoer" with NOPASSWD
https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateTmp=
【问题讨论】:
-
请查看stackoverflow.com/questions/8532304/…,看看这是否能解决您的问题。
-
我尝试了包装器,但结果相同。在我使用 shell 手动重新挂载之前,通过网页执行不会重新挂载。之后,php 上的按钮开始工作并通过包装器重新挂载文件系统。
-
您能否编辑您的问题以显示用于重新挂载根文件系统的 shell 脚本的相关行?
-
我用我通过 PHP 调用的整个 bash 脚本编辑了这篇文章