使用su模拟sudo的行为

4
我想要编写一个包装器来使su更像sudo,这样su_wrapper foo bar baz就等同于su -c "foo bar baz"
然而,我不确定如何解决这个问题。我想到了以下方法:
su_wrapper ()
{
  su -c "$@"
}

然而,在上述情况下,只能有一个单独的参数;如果有多个参数,则会失败(因为su将它们视为自己的参数)。
还有另一个问题:由于参数是通过shell传递的,我认为必须显式指定shell以避免其他问题。也许我想做的可以用伪bash表达为 su -c 'bash -c "$@"'
那么,如何使其接受多个参数?

你的动机是什么? - shx2
@shx2,我真的很累了,每次使用su时都必须引用东西,而且我不被允许在这些盒子上使用sudo。 - user2064000
1
记录一下,我不太清楚为什么有人投票关闭。这是关于计算机的一般内容。“su”和“sudo”是程序员使用的工具。 - shx2
2个回答

2
使用printf "%q"对参数进行转义,以便它们可以用作字符串输入传递给您的函数:
su_wrapper() {
    su -s /bin/bash -c "$(printf "%q " "$@")"
}

$*不同的是,即使参数包含特殊字符和空格,此方法也能正常工作。

1

你需要使用$*而不是$@

su_wrapper() {
    local IFS=' '
    su -c "$*"
}

查看 Bash 参考手册中的特殊参数部分,了解 $* 和 $@ 之间的区别。
我添加了 local IFS=' ',以防万一 IFS 被设置为其他值(在阅读了 $* 的作用后,应该清楚为什么要确保将 IFS 设置为一个空格)。

这对于 su_wrapper ls "foo bar"su_wrapper find . -name '.*' 将会失败。 - that other guy
@thatotherguy 你说得对,但是你可以始终正确引用参数来获得你想要的。 - gniourf_gniourf
但是你必须引用它们两次,不像sudo那样。 - that other guy
@thatotherguy,没错,但相应的是重定向更容易:su_wrapper "ls > file",不需要费心地使用tee或类似的工具。因此,在一方面失去的同时,在另一方面获得了。选择你的立场 :) - gniourf_gniourf
如果您想传递整个带引号的命令,为什么不直接使用su呢? - that other guy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接