AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 585751
Accepted
Ivan Kovacevic
Ivan Kovacevic
Asked: 2014-04-01 13:56:35 +0800 CST2014-04-01 13:56:35 +0800 CST 2014-04-01 13:56:35 +0800 CST

以另一个用户身份启动脚本

  • 772

我在 /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",对我有用。但是我也尝试过没有disown %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 的方法现在都会生成一个新的startpar进程(以 root 身份运行的单个进程)。在进程列表中可见:

startpar -f -- <name_of_my_init.d_script>

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

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

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

linux
  • 4 4 个回答
  • 42775 Views

4 个回答

  • Voted
  1. Best Answer
    Ivan Kovacevic
    2014-04-02T16:52:59+08:002014-04-02T16:52:59+08:00

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

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

    su - 将用户身份替换为someuser
    -c - su 参数以运行指定的命令
    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<&- &"
    

    然而,有一个更短的方法来写,没有标准输入和标准输出的数字,其中方向确实很重要:

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

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

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

    • 19
  2. dmourati
    2014-04-01T17:23:17+08:002014-04-01T17:23:17+08:00

    您可以将 init.d 中的start-stop-daemon与该--user选项一起使用。

    • 3
  3. Mr Shark
    2014-04-03T04:02:23+08:002014-04-03T04:02:23+08:00

    我还没有完全测试过这个,但我认为是这样的:

    /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
  4. Tero Kilkanen
    2014-04-01T14:53:02+08:002014-04-01T14:53:02+08:00

    你试过使用su吗?

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

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

    • 1

相关问题

  • Linux 主机到主机迁移

  • 如何在 Linux 机器上找到有关硬件的详细信息?

  • 如何在 Linux 下监控每个进程的网络 I/O 使用情况?

  • 在 RHEL4 上修改 CUPS 中的现有打印机设置

  • 为本地网络中的名称解析添加自定义 dns 条目

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve