以其他用户身份启动脚本

以其他用户身份启动脚本

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

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

并且它确实有效。但是对于每个继续运行的用户脚本(例如某些看门狗),我都看到相应的父 sudo 进程,该进程仍然处于活动状态并以 root 身份运行。这会使活动进程列表变得混乱。

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

更详细的解释:
我基本上是想为机器上的其他用户提供一种在系统启动或关闭时运行某些东西的方法,即运行位于其主目录中的相应子目录中的可执行文件(名为 .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> &"

我现在还有个问题,为什么它在没有 disown 的情况下也能正常工作?我是否应该离开否认无论如何,对于某些潜在的特殊情况,请拨打电话?

更新2

显然这也有效:

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

此调用与 sudo 调用之间有什么区别吗?我知道这可能是一个完全不同的问题。但由于我自己在这里寻找答案,也许为了这个主题,有人可以在这里澄清这一点。

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

startpar -f -- <name_of_my_init.d_script>

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

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

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

答案1

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

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

- 替代用户身份某些用户
-C-su 参数运行指定的命令
禁止- 运行不受挂断影响的命令。防止父进程终止子进程的情况。此处添加以防万一。但实际上在我的特定情况下没有效果。是否需要取决于环境(检查购物
>/dev/null- 将标准输出重定向为无,基本上禁用它。
2>&1- 将标准错误(2)输出重定向到标准输出(1),后者重定向为空
&- 分离到后台,这将把标准输入也重定向到 /dev/null。

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

还值得注意的是,您还可以关闭进程的文件描述符,而不是将其重定向到/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 时(啟動-停止啟動程式正在重定向到 /dev/null),该进程可以安全地作为守护进程在后台运行。因此,这就是避免问题所需要的(启动器) 在启动时启动脚本。

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

答案2

您可以使用啟動-停止啟動程式--user使用该选项退出 init.d。

答案3

我还没有完全测试过这一点,但我认为类似这样的事情:

/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 脚本可以通过类似启动的方式完成,但您不能确定脚本是否运行结束,因为无论如何都要关机:-)

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

答案4

您尝试过使用吗su

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

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

相关内容