使用 su 和特定命令的正确方法?

使用 su 和特定命令的正确方法?

当我需要的时候,我总是做类似的事情

su root cmd args

cmd以 root身份运行args.手册页曾经介绍过如何cmd使用目标帐户的 shell 和来调用您的内容-c,这是有道理的。

不过,在我的一台新机器上,如果我这样做的话

su root date

它抱怨

/usr/bin/date: /usr/bin/date: cannot execute binary file

我发现我可以通过-c明确使用来解决这个问题:

su root -c date

但带参数的命令仍然不起作用。如果我说

su root -c expr 1 + 2

它抱怨(即expr抱怨)“缺少操作数”。我可以解决通过做

su root -c 'expr 1 + 2'

就好像新版本su不是自动将自己的东西扔-c在那里。

也许我应该养成总是这样做的习惯

su root -c 'command args'

但我对此感到非常困惑,因为我以前从未这样做过。

最重要的是,我的问题是:

  1. su命令一路上有变化吗?
  2. 我是否一直以来都错误地调用它,但旧版本更宽容?
  3. 传递命令的正式正确方式是什么?

(较新的版本来自 util-linux 2.33.1,这对我来说非常挑剔。)

[PS 这个问题具体是关于su.我知道sudo,但引发此问题的情况并不sudo适用。]

答案1

据我通过查看 Git 修订历史记录得知,util-linuxsu实用程序的变体始终需要使用选项-c来传递要执行的命令,除非该命令是 shell 脚本。

如果该命令是为用户登录 shell 编写的 shell 脚本,-c则不需要。使用su root ./script与以 root 身份登录并运行相同$SHELL ./script(这将覆盖#!脚本中的任何行)。

如果脚本是不是为 root 用户的登录 shell 编写,您将希望将其运行为,这与以 root 身份登录并执行orsu root -c ./script相同(这将遵循脚本的-line)。./script$SHELL -c ./script#!

su据我所知,这也是在非 Linux 系统上的工作方式。


下面是有点切线:

来自 OpenBSDsu(1)手动的, 例如:

概要

su [-fKLlm] [-a auth-type] [-c login-class] [-s login-shell] [login [shell arguments]]

[...]

如果可选的shell 参数在命令行上提供,它们被传递到目标登录的登录 shell。这允许它通过-c大多数 shell 理解的选项传递任意命令。请注意,-c通常只需要一个参数;传递多个单词时必须引用它。

请注意,此处的-c选项不是 的选项,而是调用的sushell 的选项。su-c选项su是独立的,并且在 OpenBSD 上执行完全不同的操作。两者的区别在于它们在命令行上位于用户名的哪一侧。

由于 OpenBSD 只是将用户名后面的参数传递给 root 用户的 shell,因此您可以执行以下操作:

$ su root -x -c 'echo hello'
Password:
+ echo hello
hello

set -x(即,在 shell 中启用并运行命令)

由于 GNU 命令行解析有点奇怪(它会对选项进行重新排序),因此在 Linux 上不可能以完全相同的方式执行此操作,而是需要您使用来--停止选项解析:

$ su root -x -c 'echo hello'
su: invalid option -- 'x'
Try 'su --help' for more information.

su-c和解释-x为其自己的选项)

% su root -- -x -c 'echo hello'
Password:
+ echo hello
hello

su-c和传递-x给 root 用户的 shell)

答案2

su已弃用,它的存在只是为了向后兼容。

新的工作方式:

  • sudo command arg1 arg2 ...以 root 身份运行命令
  • sudo -u someone command arg1 arg2 ...运行命令为someone
  • sudo -i成为根。(您经常会看到人们使用sudo su此方法。它也可以工作,但可能会在设置环境时出现问题或su将来不再可用。)
  • sudo -u someone -i成为某人。

su需要root密码的地方,sudo使用你自己的密码。
尽管这看起来像是一个安全问题,但它实际上提供了更好的安全性。请参阅文档以获取完整信息。

很可能sudo已经在您的系统上可用,否则请安装它并确保您的用户位于以下组sudo/etc/group

相关内容