作为另一个用户启动一个脚本

我在/etc/init.d/中创build了一个脚本,它必须从其主目录中运行其他(非超级用户)用户的其他脚本,就好像他们启动了它们一样。

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

它工作。 但是,对于每个继续运行的用户脚本(例如一些看门狗),我都会看到一个相应的父级sudo进程,它仍然以root身份运行。 这在活动进程列表中创build一个混乱。

所以我的问题是: 如何从另一个用户启动(fork)另一个脚本作为另一个用户,并将其作为孤立的(独立)进程?

更详细的解释:
我基本上是试图提供给机器上的其他用户一个意思是在系统启动或系统closures时运行的东西,通过运行在其主目录中find的名为.startUp和.shutDown的各个子目录中find的可执行文件。 由于我没有find任何其他的方法来做到这一点,所以我写了我的bash脚本,完全是这样做的,我已经在/etc/init.d/中configuration它作为服务脚本(通过下面的框架示例)启动参数启动了.startUp目录中的所有内容,当它以stop参数运行时,它启动所有用户的.shutDown目录中的所有内容。

另外我也有兴趣,如果我可以使用一些现有的解决scheme来解决这个问题。

UPDATE
我查了一下,我发现这个问题: 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电话有什么区别? 我知道这可能是一个完全不同的问题。 但是,既然我在这里find答案,我自己可能为了这个话题,有人可以在这里澄清一下。

更新3
在启动机器之后,这两种使用su或sudo的方法现在都会生成一个新的startpar进程(单个进程以root身份运行)。 在进程列表中可见:

 startpar -f -- <name_of_my_init.d_script> 

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

更新4
startpar的问题已解决。 我为此开始了另一个问题:
当从rc.local或init.d启动进程时,startpar进程挂起

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

正确的答案是,对于正确的“守护进程”,标准input,标准输出和标准错误需要被redirect到/ dev / null(或一些真实文件):

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

su – 将用户身份replace为某个用户
-c – su参数来运行指定的命令
nohup – 运行一个免于hangups的命令。 防止父进程终止subprocess的情况。 以防万一。 但在我的具体情况下实际上没有影响。 是否需要取决于环境(检查店铺
> / dev / null – 将标准输出redirect为 ,基本上禁用它。
2>&1 – 将标准错误(2)输出redirect到标准输出(1),将其redirect到空
– 分离到后台,这会将标准inputredirect到/ dev / null。

这基本上就是Debian dpkg的start-stop-daemon实用程序的核心。 这就是为什么我更喜欢以这种方式启动脚本,而不是在我的代码中引入另一个外部实用程序。 当你有完整的守护进程程序需要启动时, start-stop-daemon是很有用的,然后你需要start-stop-daemon提供的附加function(例如检查指定的进程是否已经在运行,再次启动它)。

还值得注意的是,您还可以closures进程的文件描述符,而不是将其redirect到/ dev / null ,例如:

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

0 <& –closures标准input(0)
1>& –closures标准输出(1)
2>& –closures标准错误(2)输出

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

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

要么

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

然而,有一个简短的方法来写,没有数字的标准input和标准输出,方向是很重要的:

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

当文件描述符被closures或者redirect到/ dev / null( start-stop-daemon正在执行到/ dev / null的redirect)时,这个进程可以作为一个守护进程在后台运行。 所以这就是在启动时启动脚本时需要避免的问题( startpar )。

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

您可以使用--user选项在init.d之外使用start-stop-daemon 。

我还没有完全testing过,但我认为这样的:

 /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脚本可以通过类似启动的东西来完成,但是不能确定脚本运行结束,因为closures应该发生:-)

应该做的伎俩,也许你应该投入一些inputredirect,但是你将不得不担心日志文件被填充。

你有没有尝试过使用su

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

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