【问题标题】:C++ execute temp file as bash scriptC++ 将临时文件作为 bash 脚本执行
【发布时间】:2014-12-03 22:44:18
【问题描述】:

我有一个程序需要运行一个程序,我们将在我们的 linux (CentOS) 集群上并行调用 externalProg - 或者更确切地说,它需要运行许多 externalProg 实例,每个实例都在不同的内核上。每个“线程”基于几个参数创建 3 个文件——externalProg 的输入,一个告诉 externalProg 如何执行我的文件的命令文件,以及一个用于设置环境的 bash 脚本(调用制造商提供的设置脚本)和实际上用我的输入调用 externalProg。

由于这需要与未知数量的并发线程并行,并且我不想冒险覆盖另一个线程的文件,因此我正在使用

创建临时文件
mkstemp("PREFIX_XXXXXX")

对于这些输入文件。外部程序运行后,我提取相关数据并存储,并关闭临时文件(因此删除它们)。

我们将调用创建的文件(实际上根据上面的模板命名)

tmpInputs - Inputs to externalProg
tmpCommand - Input that tells externalProg how to execute tmpInputs
tmpBash - bash script to set up and call externalProg with my inputs

文件 tmpBash 看起来像

source /path/to/setup/script # Sets up environment variables
externalProg < /path/to/tmpCommand

其中 tmpCommand 只是一个简单的文本文件。

我遇到的问题实际上是执行 bash 脚本。在我的程序中,我调用了

ostringstream launchcmd;
launchcmd << "bash " << path_to_tmpBash
system(launchcmd.str().c_str());

但是什么也没发生。没有错误,没有警告,没有“找不到文件”或权限被拒绝或任何东西。我已验证文件正在创建并且内容正确。 system() 之后的其余代码已成功执行(尽管由于 externalProg 未运行而失败)。

奇怪的是,如果我回到终端并输入

bash /path/to/tmpBash

然后externalProg 执行成功。我还计算了launchcmd字符串,将其复制并粘贴到终端中,它也可以成功运行。出于某种原因,这只在我的程序中调用时才会失败。

经过一些实验,我确定 system() 在我们的集群上调用 /bin/sh。如果我将 launchcmd 更改为看起来像

/path/to/tmpBash

(所以完整的命令应该看起来像 /bin/sh /path/to/tmpBash),我得到一个权限被拒绝的错误,这并不奇怪。问题是我无法 chmod +x tmpBash 文件,而它仍然打开,如果我关闭该文件,它会被删除 - 所以我不知道如何解决这个问题。

我做错了什么,还是 system() 有一些我遗漏的细微差别?

编辑:我想补充一点,我可以成功调用类似的东西

system("echo $PATH")

并获得预期的结果(在本例中,是我的默认 $PATH)。

【问题讨论】:

  • ofstream launchcmd; 你是说ostringstream launchcmd; 吗? (只是因为你说你想使用system(launchcmd.str().c_str());
  • 我的意思是 ostringstream!我已经编辑了我的问题来解决这个问题。

标签: c++ linux multithreading bash shell


【解决方案1】:

两个不同的想法:

  • 将您的SHELL 环境变量更改为/bin/bash,然后调用system()

或:

  • 使用execve directly `execve('/bin/bash', ['/path/to/tmpBash'], environ)

【讨论】:

  • 我检查了,$SHELL 已经是 /bin/bash。我正在尝试 execve 或 execv,但奇怪的是,我仍然遇到与以前相同的问题。
  • @user3741834:你能给我一些功能示例代码吗?我很乐意从头开始修复它,但我不想从头开始写。
  • 这里一秒钟。我无法直接粘贴我的代码(安全问题),但我正在编写一个重现问题的示例。
  • 嗯。我想我可能无意中发现了问题。如果输入文件被另一个进程保持打开状态,看起来 bash 将失败(如果由 system() 调用,显然是静默)。我在其他测试中从未发现它,因为那时文件都已关闭,所以它在这些情况下有效。我重新安排了一些事情,以便关闭文件句柄,而不是 unlink()'d,现在它正在工作。我已将您的答案标记为解决方案,以防其他人发现此问题。谢谢!
猜你喜欢
  • 2013-01-19
  • 1970-01-01
  • 1970-01-01
  • 2011-03-18
  • 2015-04-07
  • 2015-08-06
  • 2014-09-19
  • 2013-12-14
  • 1970-01-01
相关资源
最近更新 更多