C++在shell中执行许多命令

C++ execute many commands in shell

本文关键字:许多 命令 执行 shell C++      更新时间:2023-10-16

我有一个C++程序,我想在一个shell中执行多个命令。我目前的解决方案使用system()函数,看起来像这样:

return_value = system(SETUP_ENVIRONMENT; RUN_USEFUL_APP_1);
... do_something_else ...
return_value = system(SETUP_ENVIRONMENT; RUN_USEFUL_APP_2);
... do_something_else ...
return_value = system(SETUP_ENVIRONMENT; RUN_USEFUL_APP_3);
...

它是有效的,但SETUP_ENVIRONMENT需要几秒钟的时间,使程序变得非常慢。但我每次都必须运行它,因为system()每次都在一个新的shell中运行。我想能够设置我的外壳一次,然后在其中运行所有命令。

execute_in_shell(SETUP_ENVIRONMENT);
return_value = execute_in_shell(RUN_USEFUL_APP_1);
... do_something_else ...
return_value = execute_in_shell(RUN_USEFUL_APP_2);
... do_something_else ...
return_value = execute_in_shell(RUN_USEFUL_APP_3);
...

我该怎么做?

我在Linux上。

或者,对于答案1,您也可以使用程序创建一个shell脚本,该脚本将运行所有有用的程序并同时执行该脚本。然后,shell不会每次都为每个特定有用的程序启动。

根据您的具体需要,您有三个合理的选择。

如果您对外部工具进行的各种调用是连贯例程的一部分,那么您可以——也可能应该——遵循@dmi的建议,编写一个可以从C++程序调用的简短shell脚本。

如果您需要在这里和那里启动过程,您可能有兴趣将shell作为一个劣质进程运行,并将您的程序附加到它上——这样,shell进程就可以与您的C++程序对话,而不是与您的终端对话。

这种方法不是很难,但有一些gotchas(例如,一些程序,如ssh、sudodocker,可能希望附加到tty)。它在大多数Unix变体的系统编程介绍(查找进程间通信和子进程)中都有很好的介绍。让我概述一下这个程序:

  1. 使用管道系统调用创建管道(stdin_r、stdinw)
  2. 使用管道系统调用创建管道(stdout_r、stdout_w)
  3. 使用管道系统调用创建管道(stderr_r、stderr_w)
  4. 使用fork系统调用复制程序
  5. 在子级中,关闭stdin_w、stdout_r、stderr_r,然后使用由stdin_r、stdout_w、stderr_w参数化的exec系统调用运行shell
  6. 在父级中,关闭stdin_r、stdout_w、stderr_w,然后现在可以在stdin_w中写入命令,并从中读取命令输出stdout_r和stderr_r

(这是故意的,非常粗略,我只是为了让你确信你在你最喜欢的教科书中找到了正确的位置才把大纲包括在内)。

有第三方库为您实现所有这些低级的东西。您可以使用boost::process(现在还不是boost的官方部分),其用法将通过完整的教程进行说明。有很多替代方案,比如pstreams。

第三种选择是避免使用shell并直接执行您使用的shell命令。这就是Rashell所遵循的方法,这是一个定义原语的OCaml库,允许可靠地组成子流程,您可以使用它来获得自己的灵感。