gpt4 book ai didi

linux - 强制CLI使用现有进程?

转载 作者:IT王子 更新时间:2023-10-29 00:48:36 25 4
gpt4 key购买 nike

将消息发送到我的linux守护程序的最简单方法是什么? myapp foo bar是否可以调用回调而不是启动新进程?与守护程序通信的标准方式是什么?我最合理的选择是将PID粘贴在/var/run中并创建一个命名管道或套接字吗?

在命令行上运行的应用与其守护进程进行通信的标准方式是什么?我假设在键入myapp foo bar时,无法要求linux调用回调吗?

最佳答案

Whats is the standard way apps which run on the command line communicate to its daemon process?


有很多方法可以做到这一点:
保管箱和信号
各种各样的位置都用于存储包含守护进程的进程ID号的“pid文件”: /var/run/<app>/<app>.pid/var/run/<app>.pid(感谢@Adam Katz进行编辑), /run/<app>/<app>.pid/run/<app>.pid(请参阅 Askubuntu: Why has /var/run been migrated to /run?)。
当知道守护进程的 pid时,命令行程序(作为单独的进程运行)可以通过以下方式与守护进程通信:
  • 将内容写到预定位置。这可以是普通文件,数据库表,也可以是服务器可读的任何方便的位置。
  • 向守护程序发送信号。在本地执行此操作的常用方法是使用kill系统调用 int kill(pid_t pid, int sig);

  • 老式示例:服务器多路复用守护程序 xinetd在收到SIGHUP后将重新读取其配置文件。
    inotify API使发送信号方法变得多余,从而使进程可以预订文件系统事件。当您不希望守护程序对每个文件更改进行操作时,使用信号很有用,因为并非每个更改都可能使文件保持有效状态,就像修改系统配置文件时一样。
    FIFO或管道
    fifo或管道只是一个特殊的文件,它阻止进程读取它,直到其他进程将其写入为止。您可以使用 mkfifo 在文件系统中创建命名管道/fifo。唯一棘手的事情是,通常应无缓冲地打开管道,例如使用 open()而不是 fopen()。脚本语言有时为方便管道的读取/写入提供了便利: Perl设置了 line-buffered模式,其中 $|=1对管道有用。
    更常见的是,您始终在命令行上看到带有 |符号分隔命令的匿名管道,这些命令作为单独的进程执行。
    socket
    那么像mySQL这样的新东西呢? mysql数据库系统由命令行客户端 mysql和服务器 mysqld组成,并且还可以为本地计算机或Internet上的其他客户端提供服务。
    MySQL使用 socket进行通信。服务器侦听套接字的连接,并派生新进程,为子进程提供套接字描述符以进行处理。当 child 完成处理后,可以退出。
    UNIX套接字和Internet套接字具有不同的 namespace 。在Linux上用C编程套接字的一个指南是 sockets chapter of the The GNU C Library manual
    无等待I/O是替代流程的替代方法。这是使用 select()系统调用在C中完成的,它允许进程等待一个或多个文件(包括套接字)上的事件或超时。 GNU C库文档包括 a no-wait I/O socket server example
    NodeJS是Java语言的服务器,使用无等待I/O编写为单线程服务器,表明这些技术在现代系统中仍然有用。
    “回调”

    I'm assuming its impossible to ask linux to call a callback when I type in myapp foo bar?


    也许是。但这值得付出麻烦。
    当您在不是Linux的“Linux”中键入 myapp foo bar时,您是在命令 shell 中键入该命令的 shell ,该 shell 是在其自己的进程中运行的程序,与其他程序分开运行。
    因此,除非您要的功能内置在命令 shell 中,否则该命令 shell 通常无法在不启动新进程的情况下将消息发送到其他程序。
    许多(但不是全部)Linux系统的默认命令 shell 是 /bin/bash。要与从 bash侦听套接字的守护程序进行通信,我们需要在 bash中打开套接字。而且,可以肯定的是,它存在!
    可以用 bash监听套接字。这是守护程序的基础:
    来自: Simple Socket Server in Bash? answer by dtmilano:

    Q: I have a simple debugging solution which writes things to 127.0.0.1:4444 and I'd like to be able to simply bind up a port from bash and print everything that comes across. Is there an easy way to do this?

    A:

    $ exec 3<>/dev/tcp/127.0.0.1/4444

    $ cat <&3


    也可以打开从bash到远程进程的套接字,即与守护程序通信:
    来自: TCP connection, bash only
    我们了解到 exec 5<>"/dev/tcp/${SERVER}/${PORT}"将TCP链接重定向到输入和输出的文件描述符5。
    并非所有 bash程序都使用TCP支持进行编译。显然,它取决于Linux发行版。至少根据 on this answer的评论 William Pursell
    除了 bash之外,还有其他shell。在* nix时代,许多炮弹都得到了发展。 ksh Jade 米 shell 。 csh C-shell。伯恩 shell sh。烟灰 shell 。维基百科保留 list of shells。而且这些 shell 程序各有优缺点,并不完全兼容彼此的格式!
    快进约30年,现在没有那么多常用的了。
    但是这里存在一个重要功能: 每个用户都可以选择自己的登录 shell 。请参阅 chsh 命令。
    因此,我要讲的是,如果 bash不支持您需要进行的通信,则可以设置命令 shell ,无需打开新进程即可发送特殊消息。这可能会节省您几毫秒的时间,通常不值得。但是没有什么能阻止你。您甚至可以按照 https://stackoverflow.com/a/209670/103081中的建议设置一个ipython命令 shell ,并且python可以导入与专用守护程序进行套接字通信所需的大多数内容。

    关于linux - 强制CLI使用现有进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26636661/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com