我想在脚本中创建一个新组,将当前用户分配给该组,重新加载用户的组并继续执行需要新组的命令。
在这个相关问题我找到了一些不错的方法来避免生成新的内壳,因为最终我必须退出该内壳才能进入脚本正在运行的当前内壳。但问题是这exec
会完全替换当前壳,因此脚本会停止。例如:
#!/bin/bash
exec sg GROUP newgrp $(id -gn)
echo hello
此处脚本可以顺利切换组并避免需要双重退出(例如通过 SSH),但echo
从未运行。
我可以运行一个不同的脚本,其中sg
包含需要该组的命令,然后在脚本结束时更新最终的组,这只是为了方便用户,但这似乎不是最佳选择。有没有办法在运行脚本时干净地更新组分配?
答案1
不幸的是,据我所知,获取具有最新用户组的 shell 的唯一方法是执行类似 的操作su - $(whoami)
,这需要当前用户再次输入密码,或者使用newgrp
/ sg
。为了避免用户需要再次进行身份验证,我们只能使用后者。
#!/bin/bash
# The new group that will be created and have the current user added to.
GROUP_NEW=testgroup
if [ -z "$GROUPS_LIST_ADDED" ]; then
sudo groupadd "$GROUP_NEW"
sudo usermod --append --groups "$GROUP_NEW" "$(whoami)"
# Run this script again with the new group added to the groups list
# and set as the primary group. We will run it once more to restore
# the primary group to the original value.
export GROUP_ORIGINAL="$(id -gn)"
export GROUPS_LIST_ADDED=1
# We ensure that script arguments are independently sub-quoted.
exec sg "$GROUP_NEW" "exec '$0' $(printf "'%s' " "$@")"
elif [ -z "$GROUP_PRIMARY_RESTORED" ]; then
# Rerun this script once more to restore the primary group.
export GROUP_PRIMARY_RESTORED=1
exec sg "$GROUP_ORIGINAL" "exec '$0' $(printf "'%s' " "$@")"
fi
# Continue on with this script. The current user now has the new group added to
# it's groups list.
id
我们需要使用两次重新执行sg
,一次将新组添加到“组列表”,另一次将“主组”设置回原始主组。如果我们尝试在一行嵌套的 exec 中执行此操作,则必须对脚本的参数使用双转义引号,这很复杂且不清楚。出于这个原因,我选择拆分 exec 调用sg
。