2016-01-07 164 views
2

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

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中运行。 我希望能够安装我的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并通过它发送命令。 –

+1

http://stackoverflow.com/questions/245600/using-a-single-system-call-to-execute-multiple-commands-in-c – mstruebing

+1

@mstruebing:这假设你知道哪些程序运行,何时,以及哪些参数。管道是更好的解决方案。 – MSalters

回答

0

根据您的具体需要,您有三个合理的选择来完成此操作。

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

如果您不是需要在这里和那里启动程序,你可能有兴趣进入运行外壳作为劣等过程和程序连接到它 - 这样,而不是与你的终端进行交谈,外壳工艺会谈你的C++程序。

这种方法也不是很困难,但有几个陷阱(例如,像SSH,须藤泊坞窗某些程序可能期望被安装到TTY)。对于任何Unix变体,系统编程的大多数介绍(查找进程间通信和子进程)都有很好的介绍。让我概括了程序:

  1. 使用管道系统调用创建管道(stdin_r,stdin_w)
  2. 使用管道系统调用创建管道(stdout_r,stdout_w)
  3. 使用管道系统调用创建管道(stderr_r,stderr_w)
  4. 使用系统调用fork复制程序
  5. 在孩子,你接近stdin_w,stdout_r,stderr_r,并使用 exec系统调用由stdin_r,stdout_w parametrised,stderr_w到 运行shell。
  6. 在父项中,关闭stdin_r,stdout_w,stderr_w,并且您现在可以在stdin_w中写入命令,并从 stdout_r和stderr_r中读取命令输出。

(这个故意非常粗略,我只包括轮廓,以便您确定在您最喜爱的教科书中找到了正确的位置)。

有第三方库为您实现所有低级别的东西。您可以使用boost::process(现在还不是升级的官方部分),其用法用full tutorial来说明。有plenty of alternatives,如pstreams

第三个选择是避免使用shell并执行直接使用的shell命令。这是Rashell之后的方法,它是一个OCaml库,用于定义允许可靠组合子流程的基元,您可以使用它来获取灵感。

1

除了回答1,您还可以使用您的程序创建一个shell脚本,它将运行所有有用的程序并立即执行此脚本。然后每个特定的有用程序都不会启动shell。

+1

我不确定设置环境是什么,但据我了解,大部分时间都是由它完全消耗的,对吧?也许你可以为你的主进程设置所需的环境,然后所有派生的进程会自动继承它,所以你不需要为每个特定的有用程序进行设置?或者想一些其他方式来共享环境给他们(如果可能的话)(即通过文件或共享内存) – dmi