以其他用户身份启动脚本


12

我已经在/etc/init.d/中创建了一个脚本,该脚本必须从其主目录中的其他(非root用户)用户运行其他几个脚本,就像他们启动了它们一样。

我使用以下命令启动这些脚本: sudo -b -u <username> <script_of_a_particular_user>

而且有效。但是对于每个继续运行的用户脚本(例如某些看门狗),我看到一个相应的父sudo进程,该进程仍处于活动状态并以root身份运行。这会在活动进程列表中造成混乱。

所以我的问题是:如何以另一个用户身份从现有bash脚本启动(分支)另一个脚本并将其保留为孤立的(独立的)进程?

更详细的解释:
我基本上是想通过运行在其主目录中名为.startUp和.shutDown的各个子目录中的可执行文件,向计算机上的其他用户提供一种在系统启动或系统关闭时运行内容的方法。由于我没有找到其他方法来执行此操作,因此我编写了可以完全执行此操作的bash脚本,并已在/etc/init.d/中将其配置为服务脚本(通过遵循框架示例),因此在运行时使用start参数,它将从.startUp目录启动所有内容;当使用stop参数运行时,它将从所有用户的.shutDown目录启动所有内容。

另外,如果我可以使用一些现有的解决方案来解决此问题,我也很感兴趣。

更新
我环顾了一下,发现了这个问题:https : //unix.stackexchange.com/questions/22478/detach-a-daemon-using-sudo

在那里接受答案,使用:sudo -u user sh -c "daemon & disown %1",对我有用。但是我也尝试了不放弃%1的情况,这是相同的。因此,这正是我所期望的:

sudo -u <username> bash -c "<script_of_a_particular_user> &"

现在,我的另一个问题是,为什么它会不加修改地起作用?无论是否有某些特殊情况,我是否仍应保留拒绝通知?

更新2

显然这也可行:

su <username> -c "<script_of_a_particular_user> &"

这个调用和sudo调用之间有什么区别吗?我知道这可能是一个完全不同的问题。但是由于我自己在这里找到答案,也许出于这个主题的缘故,有人可以在这里进行澄清。

更新3在我引导计算机之后
,这两种使用su或sudo的方法现在都会产生一个新的startpar进程(以root身份运行的单个进程)。在进程列表中显示为:

startpar -f -- <name_of_my_init.d_script>

为什么会产生此过程?显然我做错了,因为没有其他init.d脚本正在运行此进程。

更新4
解决了startpar的问题。我对此提出了另一个问题:从rc.local或init.d启动进程时
startpar进程挂起

还有一个问题需要进一步讨论非特权用户的启动机制:
为普通用户(非root用户)提供初始化和关闭自动运行功能

Answers:


18

正确的答案是,为了进行适当的“守护进程”,需要将标准输入,标准输出和标准错误重定向到/ dev / null(或某些真实文件):

su someuser -c "nohup some_script.sh >/dev/null 2>&1 &"

-替代用户身份SomeUser的
-c -苏参数运行指定的命令
的nohup -运行命令不被挂起。为了防止父进程终止子进程的情况。以防万一。但实际上对我的情况没有任何作用。是否需要它取决于环境(请检查shopt
> / dev / null-将标准输出重定向为,基本上将其禁用。
2>&1-将标准错误(2)输出重定向到标准输出(1),重定向到null
-分离到后台,这会将标准输入也重定向到/ dev / null。

本质上,这正是Debian dpkg的start-stop-daemon实用程序的核心功能。这就是为什么我更喜欢以这种方式启动脚本,而不是在代码中引入另一个外部实用程序调用的原因。start-stop-daemon在需要启动完整的守护程序且随后需要start-stop-daemon 提供的其他功能的情况下很有用(例如,检查指定的进程是否已在运行,以便它将不会再次启动)。

还值得注意的是,您也可以关闭进程的文件描述符,而不是将它们重定向到/ dev / null,例如:

su someuser -c "some_script.sh 0<&- 1>&- 2>&- &"

0 <&-关闭标准输入(0)
1>&-关闭标准输出(1)
2>&-关闭标准误差(2)输出

只要指定了较长的文件描述符号,<>符号的方向就无关紧要。所以这同样好:

su someuser -c "some_script.sh 0>&- 1>&- 2>&- &"

要么

su someuser -c "some_script.sh 0<&- 1<&- 2<&- &"

但是,有一种简短的写法,其中方向很重要,而没有stdin和stdout的数字:

su someuser -c "some_script.sh <&- >&- 2>&- &" 

当文件描述符关闭或重定向到/ dev / null时(start-stop-daemon正在重定向到/ dev / null),该进程可以安全地在后台作为守护程序运行。所以这是什么是需要避免的问题(startpar与在开机时启动脚本)。

我已经从最初的想法实现了整个解决方案,并将其放在GitHub上:https :
//github.com/ivankovacevic/userspaceServices


伊万,使用su或su -login更好吗?我读过su的书,但对于这种特殊情况我不理解。
马西莫'18

1
@Massimo,很抱歉我的回复延迟!检查以下问题:unix.stackexchange.com/questions/318572/…那里有一个更好的手册页对此进行了说明。基本上,区别在于设置工作目录和环境变量。我会说,对于这样的用例(以另一个用户的身份做事),使用-login可能是一个更可取的选择
Ivan Kovacevic


2

我尚未对此进行全面测试,但我认为类似:

/sbin/start-stop-daemon --background --start --exec /home/USER/.startUp --user USER --pidfile=/home/USER/.startUp.pid --make-pidfile

在启动时,然后

/sbin/start-stop-daemon --stop --user USER --pidfile=/home/USER/.startUp.pid

关闭时。

.shutDown脚本的处理可以通过诸如启动之类的方法来完成,但是您不能确定脚本会运行到结尾,因为无论如何都会发生关机:-)

应该可以解决问题,也许您应该进行一些输入重定向,但随后您将不得不担心日志文件已被填充。


2
本质上,这将起作用!start-stop-daemon可以在引导或其他方式成功启动进程。我已经测试过了 并且它也摆脱了挂起startpar进程的问题。但是,您在开始呼叫中也缺少--chuid USER。没有它,它将以根用户身份启动该过程。pid文件也可能应该写入/ var / run /,因为否则它将在用户主目录中生成一个根目录拥有的文件。但是,在我看来,对于通用脚本而言,启动start-stop-daemon似乎有点过头了。在我试图解释原因的地方检查我的答案。
伊万·科瓦切维奇

1

您是否尝试过使用su

su -c /home/user/.startUp/executable - user

-c 告诉su执行命令,最后一个参数是用户按原样执行命令。


是的,可以,但是带有一些引号和“&”号。而且我发现这样写起来更干净:su <username> -c“ /some/path/script.sh&”基本上,我使用了sudo,因为它看起来更干净,但是现在使用:sudo- u <用户名> bash -c“ /some/path/script.sh&”。不知道两者之间是否有任何区别
Ivan Kovacevic 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.