通常以其他用户身份执行作业,我们可以执行 sudo -u <user> <cmd>
.但是,在永久过程的情况下,我们必须这样做:
exec su -s /bin/sh -c 'exec "$0" "$@"' username -- /path/to/command [parameters...]
引用:https://superuser.com/questions/213416/running-upstart-jobs-as-unprivileged-users
这有什么不同?这是什么意思?此外:
su -s /bin/bash -c bash username -- /path/to/command [parameters...]
似乎不起作用!
最佳答案
第一个:
exec su -s /bin/sh -c 'exec "$0" "$@"' username -- /path/to/command [parameters]
开始
upstart
作为 root 用户以外的用户的作业旨在允许更改用户 ID 而不会留下中间进程;所以它以以下方式运行:exec su -s sh
用 su 替换调用此命令的进程,运行 shell sh
-c 'exec "$0" "$@"'
来自 shell sh
的调用exec
在 --
之后传递的命令和参数($0
是命令行的第一个参数,--
之后,$@
是之后的所有参数)最终产品正在运行
/path/to/command
就好像它是直接从命令中调用的 username
指定的;留下一个看起来像这样的进程树:su [as root] -> /path/to/command [as username]
如果您没有使用
exec
调用它,那么你最终会得到一个看起来像这样的进程树:upstart_launcher [as root] -> su [as root] -> sh [as username] -> /path/to/command [as username]
(我不知道 upstart_launcher 进程此时会是什么样子;我没有带有 upstart 的系统来检查这个;但是会有一个进程遗留下来)
现在,其中一个重要的元素是它只调用
exec /path/to/command [arguments…]
,就好像它是从命令行输入的一样。当我们将其与第二个命令行进行比较时;大多数发生的事情是相似的,但并不完全相同:
su -s /bin/bash -c bash username -- /path/to/command [parameters...]
为什么它不起作用?好吧,您已经要求它做一些不同的事情;在这种情况下;您要求它运行命令
bash
从外壳 bash
.因为你没有传入
$0
或 $@
, --
之后的所有内容被忽略,因为它没有传递到 -c
对于被调用的 shell。有和没有 exec 的例子
这会折叠进程树,删除中间
sh
- 这是一种防止深层进程树的内务管理机制。跳过所有高管(
su -s /bin/sh -c '"$0" "$@"' proxy -- pstree -aApl
):bash,1
`-bash,1014
`-su,1017 -s /bin/sh -c "$0" "$@" proxy -- pstree -aApl
`-sh,1018 -c "$0" "$@" pstree -aApl
`-pstree,1019 -aApl
添加内部 exec (
su -s /bin/sh -c 'exec "$0" "$@"' proxy -- pstree -aApl
) - 注意缺少的第二级 sh
:bash,1
`-bash,1014
`-su,1020 -s /bin/sh -c exec "$0" "$@" proxy -- pstree -aApl
`-pstree,1021 -aApl
添加内部和外部 exec (
exec su -s /bin/sh -c 'exec "$0" "$@"' proxy -- pstree -aApl
) - 注意缺少的外部级别 bash
,以及 1014
的事实pid 与先前 bash 调用中存在的 pid 相同:bash,1
`-su,1014 -s /bin/sh -c exec "$0" "$@" proxy -- pstree -aApl
`-pstree,1022 -aApl
关于node.js - 以其他用户身份执行作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40189961/