简洁版本
TL;DR - 当以提升的权限*运行 nemo/nautilus 时,权限选项卡上会有大量用户/组...它们都挤在不可搜索的下拉菜单中,没有任何热键支持。正在寻找调整/备用文件管理器/chmod gui-wrappers,以便我可以从 GUI 更改所有权,而无需担心可访问性问题。有什么建议吗?
更多信息
我在 Virtualbox 中安装了多个版本的 Ubuntu 18.04。我主要使用Cinnamon 桌面/nemo 到此为止。
总体而言,我对这个桌面非常满意。但基于 GUI 的所有权变更(从 root 开始)令人沮丧,因为大量条目都塞在下拉列表中,我无法搜索,也无法使用热键(例如按热键跳转r到“root”等)。启动终端很可靠,但当我急着输入名称时速度很慢。
注意:当从非 root 帐户运行文件管理器时,这并不是什么问题,因为所有者不可编辑并且只显示几个组。
我通常会遇到这种情况,因为我尝试修复当前用户不拥有的共享文件夹的所有权权限。而且它通常不会像运行单个chown -R
命令那样快速和简单。
我在以下地方遇到过同样的可访问性设计:
- nemo v.3.6.5(ubuntu 18.04/gnome+cinnnamon)
- nemo v4.2.3(在一个流行的子发行版中,显然我不再被允许在这里提及)
- nautilus v3.26.4(ubuntu 18.04/gnome)。
标准:
我有兴趣找到一个符合以下标准的基于 GUI 的解决方案:
- 适用于 Ubuntu 18.04 / bionic 的一些版本(因为我更喜欢 LTS 版本)
- 50-100 个用户/群组列表的用户可访问性良好(例如,至少尝试处理非平凡的列表大小,例如通过热键支持、搜索过滤器、隐藏服务帐户的选项或其他内容)
- 在 root 下运行没有问题(例如 via
pkexec
或其他方式)。之所以提到这一点,是因为我之前遇到过一些应用程序完全拒绝在 root 下运行。
此时,我只是希望有人知道我不知道的选项......我并不特别关心这是否是针对 nemo 的调整、系统配置、一些晦涩的构建选项、不同的文件管理器/桌面环境、一些包装 GUI 的外部应用程序chown
(只要我可以将它放入nemo-action
并传递给它路径)等。主要只是想避免在匆忙时启动终端并手动输入较长名称的额外麻烦。
* 另外,当我说我“以 root 身份运行”/“以提升的权限运行”时,我指的是 nemo/nautilus UI 中出现的选项,而不是我直接使用 sudo/pkexec/等启动。
查看对话框问题的步骤:
- 在桌面上或非 root 帐户拥有的任何位置创建名为“test”的文件夹
- 在 Nemo 中,右键单击 > “以 root 身份打开” > 输入密码。或者对于 nautilus,运行
pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY nautilus
以管理员权限打开。 - 使用管理实例,右键单击“测试”文件夹 > 属性 > 权限选项卡
- 请注意,所有服务帐户和组都显示出来,没有过滤它们的方法/没有复选框来隐藏它们。请注意,按下下拉菜单中的“R”不会跳转到或选择“root”(或以“R”开头的第一个帐户)。就我而言,显示了大约 50 个用户(其中 3 个是非服务帐户)和大约 80 个组(其中 8 个与服务帐户无关)。对我来说,这是一场可访问性的噩梦,它使搜索东西几乎和需要启动终端并手动输入一样痛苦。
我尝试过的:
如果我发现任何有效的方法,我会跟进,但到目前为止,我已经尝试了以下方法:
- 允许几乎就是我所寻找的,只是它似乎需要输入名称,而不是从列表/下拉列表/等中选择。不幸的是,我目前完全没有 GTK 技能(虽然如果没有人有更好的建议,我可能会在有更多时间时重新考虑这一点)。
- Ubuntu 18.04.2/gnome - 最初无法弄清楚如何以 root 身份运行,但
pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY nautilus
最终成功了。毫不奇怪,这似乎与 nemo 有同样的问题。 - Ubuntu 18.04.2/cinnamon - 之后安装 cinnamon并按照上面提到的方式运行 nemo,但这并不能达到我想要的效果。
- Kubuntu 18.04 - 找不到以 root 身份启动 dolphin 的方法,因此无法测试。当我以 livedisc 上的默认非 root 帐户运行时,用户/组字段对我来说是灰色的。听起来这是 v17 的问题,我必须获得 v18 才有机会以 root 身份运行。
- 更新 1:已找到本网站提到 Eiciel。尝试了
sudo apt install -y eiciel
一下touch /tmp/foo.txt && eiciel /tmp/foo.txt
看起来很酷,但不幸的是,要么它不允许更改所有者,要么我只是不知道该怎么做(似乎添加用户/组添加到 ACL,而不是替换当前所有者/组)。 - 更新 2:在基于 ubuntu 18.04 的子发行版上测试了 thunar。当我运行它
sudo thunar /
并转到权限选项卡时,组下拉菜单存在与 nemo/nautilus 相同的问题,尽管以 root 身份运行,它甚至不允许我编辑用户。 - 更新 3:在 kubuntu 中使用 krusader 进行测试。以 root 身份运行,在权限对话框中,所有者/拥有组字段只是文本输入字段(例如,您必须将其输入出来)。
截屏
在 (admin/root/pkexec) nemo 和 nautilus > 属性 > 权限选项卡中出现的不可搜索的下拉菜单包含大量条目并且不支持热键。
答案1
更新:没有听到任何其他回应,自从我更新它以添加多选支持以来,它已经运行得更好了,所以我想,由于没有其他选择,我会接受这个作为我的答案
更新 #2:我已经创建了一个脚本,它可以完成所有繁重的工作并自动执行以下步骤。您可以在以下位置找到有关该脚本的更多信息我的 github。
我仍然对其他答案非常感兴趣,但我至少找到了一个有点黑客的解决方法(bash + yad + pkexec),我认为这比没有要好......也继续将它作为功能请求提交到nemo项目中,所以希望其中一个人可以找到比我这里的更好的东西。
假设
我的解决方法假设如下:
- 您已安装 yad:
sudo apt install -y yad
- 您不介意在单独的对话框中编辑用户/组(例如,根本不处理 chmod 内容;只处理 chown)
- 你不介意为初始设置做一些准备工作
- 您对我非常不成熟的用户/群组选择表示同意。
- 您同意下拉菜单不支持按键/自动完成。
- policykit 使得非 root nemo 每次都会收到身份验证提示,但 root nemo 永远不会收到提示。如果您希望降低安全性,可以随时更改 policykit 设置(但不推荐)。
- 您相信我没有弄乱策略工具包设置(它可以为我运行并且似乎提示正确,但我无法保证其安全性)
- 由于后台交给 bash 脚本执行,导致性能不佳,对此你并不介意
设置
这将需要创建 3 个文件并编辑第四个文件(用于 policykit 定义)。
- 首先,继续创建一个临时文件夹和 3 个临时文件:
mkdir /tmp/chown-gui
cd /tmp/chown-gui
# create temp files - we'll rename these later when they get moved
touch tmp-pkexec tmp-sh tmp-action
- 创建主 bash 脚本
文件 #1:tmp-sh(最终位于 /usr/bin/chown-gui-wrapper)
#!/bin/bash
# v1.2.0
# Last updated on 2019 Oct 15
prompt_on_multiple_files="true";
default_to_once_for_all_paths_if_no_prompt="true";
apply_once_for_all_paths="false";
has_multiple_paths="false";
second_file="$2";
if [[ "" != "${second_file}" ]]; then
has_multiple_paths="true";
if [[ "true" == "${prompt_on_multiple_files}" ]]; then
prompt_response=$( yad --center --button="gtk-ok:0" --title "Multiple Paths Detected" --form --field="\n How would you like to apply permissions? \n:LBL" "" --field="${label_hpadding}:CB" "Set permissions once and apply it to all paths\!Set permissions for each path individually");
if [[ ! $prompt_response =~ ^.*individually.*$ ]]; then
apply_once_for_all_paths="true";
fi
elif [[ "true" == "${default_to_once_for_all_paths_if_no_prompt}" ]]; then
apply_once_for_all_paths="true";
fi
fi
#echo "prompt_on_multiple_files=\"${prompt_on_multiple_files}\"";
#echo "default_to_once_for_all_paths_if_no_prompt=\"${default_to_once_for_all_paths_if_no_prompt}\"";
#echo "apply_once_for_all_paths=\"${apply_once_for_all_paths}\"";
popup_title="Please select the user and group owners";
popup_text="Please select the user and group owners for the following path:"
label_hpadding=" ";
for filepath in "${@}"; do
#echo "filepath in array is $filepath";
if [[ ! -e "${filepath}" ]]; then
ERROR_MSG="ERROR: File '${filepath}' does not exist";
notify-send --icon=error "${ERROR_MSG}";
echo "${ERROR_MSG}";
continue;
fi
filename=$(basename "${filepath}")
current_user=$(stat -c "%U" "${filepath}");
current_group=$(stat -c "%G" "${filepath}");
show_checkbox="false";
if [[ -d "${filepath}" ]]; then
show_checkbox="true";
fi
# get list of non-service accounts/groups
users_list=$(getent passwd {1000..60000}|awk -F: '{print $1}'|tr '\n' ' ');
groups_list=$(getent group {1000..60000}|awk -F: '{print $1}'|tr '\n' ' ');
sorted_user_list=$(echo $(printf '%s\n' root $users_list | sort -u)|sed -E "s/\\b($current_user)\\b/^\\1/g"|tr ' ' '\!');
sorted_group_list=$(echo $(printf '%s\n' root $groups_list | sort -u)|sed -E "s/\\b($current_group)\\b/^\\1/g"|tr ' ' '\!');
#echo "show_checkbox: ${show_checkbox}";
if [[ "true" == "${show_checkbox}" ]]; then
formdata=$(yad --center --button="gtk-cancel:1" --button="gtk-ok:0" --title "${popup_title}" --form --field="\n${label_hpadding}${popup_text}${label_hpadding}\n:LBL" "" --field="${label_hpadding}Path:${label_hpadding}:RO" "${filepath}" --field="${label_hpadding}User:${label_hpadding}:CBE" "${sorted_user_list}" --field="${label_hpadding}Group:${label_hpadding}:CBE" "${sorted_group_list}" --field "\n:LBL" "" --field="Apply Recursively?:CHK" "FALSE");
else
formdata=$(yad --center --button="gtk-cancel:1" --button="gtk-ok:0" --title "${popup_title}" --form --field="\n${label_hpadding}${popup_text}${label_hpadding}\n:LBL" "" --field="${label_hpadding}Path:${label_hpadding}:RO" "${filepath}" --field="${label_hpadding}User:${label_hpadding}:CBE" "${sorted_user_list}" --field="${label_hpadding}Group:${label_hpadding}:CBE" "${sorted_group_list}");
fi
if [[ "" == "$formdata" ]]; then
echo "user pressed cancel for filepath '${filepath}'";
continue;
fi
#echo "formdata=\"${formdata}\"";
new_user=$(echo "${formdata}"|awk -F'|' '{print $3}');
new_group=$(echo "${formdata}"|awk -F'|' '{print $4}');
is_recursive="FALSE";
if [[ "true" == "${show_checkbox}" ]]; then
is_recursive=$(echo "${formdata}"|awk -F'|' '{print $6}');
fi
#echo "new_user=\"${new_user}\"";
#echo "new_group=\"${new_group}\"";
#echo "is_recursive=\"${is_recursive}\"";
RECURSIVE_FLAG='';
if [[ "TRUE" == "${is_recursive}" ]]; then
RECURSIVE_FLAG='-R';
fi
if [[ "true" == "${has_multiple_paths}" && "true" == "${apply_once_for_all_paths}" ]]; then
chown $RECURSIVE_FLAG "${new_user}":"${new_group}" "${@}";
break;
else
chown $RECURSIVE_FLAG "${new_user}":"${new_group}" "${filepath}";
fi
done
- 创建包装器脚本
文件 #2:tmp-pkexec(最终位于 /usr/bin/pkexec-chown-gui-wrapper)
#!/bin/bash
# v1.2.0
# Last Updated: 2019 Oct 15
yad_installed=$(which yad);
if [[ "" == "${yad_installed}" ]]; then
ERROR_MSG="ERROR: Missing dependency 'yad'; Please run: sudo apt install -y yad;";
notify-send --icon=error "${ERROR_MSG}";
echo "${ERROR_MSG}";
exit;
fi
pkexec --user root env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY /usr/bin/chown-gui-wrapper "${@}"
- 创建 nemo 动作(以便它出现在右键菜单中)
文件 #3:tmp-action(最终位于 /usr/share/nemo/actions/change-owner.nemo_action)
[Nemo Action]
Name=Change Owner/Group
Comment=GUI wrapper for chown
Selection=s
Exec=/usr/bin/pkexec-chown-gui-wrapper %F
Icon-Name=gnome-settings
Extensions=any;
Quote=double
- 将所有临时文件复制到适当的位置并设置权限
cd /tmp/chown-gui
sudo cp tmp-sh /usr/bin/chown-gui-wrapper;
sudo cp tmp-pkexec /usr/bin/pkexec-chown-gui-wrapper;
sudo cp tmp-action /usr/share/nemo/actions/change-owner.nemo_action;
sudo chown root:root /usr/bin/chown-gui-wrapper;
sudo chown root:root /usr/bin/pkexec-chown-gui-wrapper;
sudo chown root:root /usr/share/nemo/actions/change-owner.nemo_action;
sudo chmod 755 /usr/bin/chown-gui-wrapper;
sudo chmod 755 /usr/bin/pkexec-chown-gui-wrapper;
sudo chmod 644 /usr/share/nemo/actions/change-owner.nemo_action;
# This part is needed if you want to be able to use this in nemo with
# single-file selections AND multiple-file selections BUT NOT when
# there is NO selection (e.g. directory background).
# Nemo's 'Selection' option doesn't currently allow multiple values
# and 'm' only considers "2+" and 'a' considers "0+"
# whereas this gives us "1,2+"
#
sudo cp -a /usr/share/nemo/actions/change-owner.nemo_action /usr/share/nemo/actions/change-owner-single-file.nemo_action;
sudo mv /usr/share/nemo/actions/change-owner.nemo_action /usr/share/nemo/actions/change-owner-multiple-files.nemo_action;
sudo sed -i -E 's/^(Selection)=s/\1=m/' /usr/share/nemo/actions/change-owner-multiple-files.nemo_action;
- 确保安装了 yad。没有它,这绝对行不通。你可以用 zenity 替换它(但由于 yad 是 zenity 的一个分支,所以这对我来说似乎毫无意义)
sudo apt install -y yad
- 创建 PolicyKit 例外情况
您可能已经有或还没有 pkexec.policy 文件。如果有,则只需添加块<action>...</action>
。如果没有该文件,则创建它(chmod 664
和chown root:root:
)并复制整个<policyconfig>...</policyconfig>
块。
要编辑/创建的 Policykit 文件:
/usr/share/polkit-1/actions/org.freedesktop.policykit.pkexec.policy
内容(新文件):
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<action id="org.freedesktop.policykit.pkexec.run-chown-gui-wrapper">
<description>GUI wrapper for chown</description>
<message>Authentication is required to run chown-gui-wrapper</message>
<icon_name>gnome-settings</icon_name>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/bin/bash</annotate>
<annotate key="org.freedesktop.policykit.exec.argv1">/usr/bin/chown-gui-wrapper</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">TRUE</annotate>
</action>
</policyconfig>
- 确认设置
# make dummy file to test with
echo dummy > /tmp/foo.txt
# check that you get the gui pop-up
# no need for root, just confirm gui comes up, then you can cancel
/usr/bin/chown-gui-wrapper /tmp/foo.txt
# check that you get the gui pop-up
# might prompt for auth, just confirm gui comes up, then you can cancel
/usr/bin/pkexec-chown-gui-wrapper /tmp/foo.txt
如果从终端启动,则只需确认 nemo 上下文菜单选项有效并且一切正常。
截图/预览
使用 yad 创建的弹出窗口
它会自动过滤到根+非服务用户/组:
注意:下拉菜单实际上是按 AZ 降序排列的;但我在图片中编辑了我的用户名...因为这是互联网 :-)