通过命令行向程序发送消息

Posted

技术标签:

【中文标题】通过命令行向程序发送消息【英文标题】:Send messages to program through command line 【发布时间】:2010-09-05 20:14:27 【问题描述】:

我有这个程序,我们称它为 Host。 Host 做了各种好事,但它需要能够在运行时接受命令行输入。这意味着它必须以某种方式发送它的其他进程数据然后退出。例如,我需要能够做到这一点:

./Host --blahblah 3 6 3 5

这应该以某种方式最终调用 Host 中的某个函数调用

handleBlahBlah(int x1, int y1, int x2, int y2)
  //do some more sweet stuff

Host是C程序,不需要支持多实例。

Amarok 音乐播放器就是一个例子。随着 Amarok 的运行和播放,您可以键入“amarok --pause”,它会暂停音乐。

我需要能够在 Linux 或 Windows 中执行此操作。最好是Linux。

什么是最简洁的实现方式?

【问题讨论】:

你想在程序已经运行时传递参数吗?这是为什么操作系统编程的? 【参考方案1】:

我见过的一种技术是让您的Host 程序仅仅是您真正程序的“外壳”。例如,当您正常启动应用程序时(例如:./Host),程序将分叉到代码的“主应用程序”部分。当您以建议您希望向正在运行的实例发出信号的方式启动程序时(例如:./Host --send-message restart),程序将分叉到代码的“消息发送者”部分。这就像将两个应用程序合二为一。不使用fork 的另一个选项是使Host 纯粹是一个“消息发送者”应用程序,并将您的“主应用程序”作为一个单独的可执行文件(例如:Host_core),Host 可以单独启动。

程序的“主应用”部分需要打开某种通信通道来接收消息,而“消息发送者”部分需要连接到该通道并使用它来发送消息。有几种不同的选项可用于在进程之间发送消息。一些更常见的方法是pipes 和sockets。根据您的操作系统,您可能有其他可用选项;例如,QNX 有channels,BeOS/Haiku 有BMessages。您也许还可以找到一个巧妙地封装了此功能的库,例如 lcm。

【讨论】:

【参考方案2】:

这里没有人说过: “你不能从这里到那里”。

命令行仅在调用程序时可用。

fillinthename 运行后调用“fillinthename arguments ...”与fillinthename 进行通信的示例只能通过使用两个相互通信的程序实例。

其他答案建议了实现沟通的方法。

amarok 类程序需要检测另一个实例的存在 为了知道它必须扮演什么角色,它的主要作用是 持久消息接收器/服务器,或一枪的次要角色 消息发送者。

进行了编辑,以实际显示单词 fillinthename。

【讨论】:

【参考方案3】:

我建议使用Unix socket 或D-Bus。如果您熟悉 Unix 套接字编程并且只需要一些操作,那么使用套接字可能会更快,而 D-Bus 可能更容易专注于以熟悉的面向对象方式实现功能。

看看Beej's Guide to Unix IPC,尤其是Unix sockets的章节。

【讨论】:

【参考方案4】:

如果你在 Windows 上,我会告诉你使用隐藏窗口来接收消息,但由于你使用了 ./,我假设你想要基于 Unix 的东西。

在这种情况下,我会选择named pipe。 Sun 有一个关于命名管道的tutorial 可能有用。

程序可能会创建管道并进行监听。您可以有一个单独的命令行脚本来打开管道并将其命令行参数回显给它。

可以修改您的程序以支持命令行发送,而不是使用单独的脚本。在这种情况下,你会做同样的基本事情。你的程序会查看它的命令行参数,如果适用,打开通往程序“主”实例的管道,然后发送参数。

【讨论】:

+1 我已经多次使用这种命名管道方法并且效果很好。在主程序需要将数据返回到命令行脚本/程序的情况下,我还使用了 UNIX 套接字。【参考方案5】:

所以,我可能在这里忽略了要点,但是默认情况下,C 程序的 main 函数需要两个参数; argc,参数数量(至少一个)的计数,以及 argv(或 arg 向量),参数列表。您可以只解析参数并调用正确的方法。 例如:

 int main(int argc, *argv[])
 
     /*loop through each argument and take action*/
      while (--argc > 0)
      
           printf(%s%s, *++argv, (argc > 1) ? " " : "");
      
  

会将所有参数打印到屏幕。我不是C大师,所以我希望我没有犯任何错误。

编辑:好的,他在追求别的东西,但在编辑问题之前还不是很清楚。不必跳我的代表...

【讨论】:

【参考方案6】:

如果需要跨平台,您可能需要考虑让正在运行的实例侦听 TCP 端口,并让您从命令行启动的实例向该端口发送消息。

【讨论】:

以上是关于通过命令行向程序发送消息的主要内容,如果未能解决你的问题,请参考以下文章

linux shell命令行向udp端口发送数据

执行歌词命令时出现此错误:DiscordAPIError:无法发送空消息

VB6 应用程序通过 winsock 发送 UDP 广播消息 - 仅每秒发送一次消息

发送自发的短暂不和谐消息

Linux - 从管道读取的孩子接收发送到标准输出的调试消息

讨论:动态链接库如何给主程序发送自定义消息?