将C++程序的返回值传递给Bash脚本

8

我有一个在Linux上运行的C++程序,计算一个double类型的结果。我想要编写一个bash脚本来运行这个程序多次,并对这些结果进行平均。为了简单起见,考虑以下代码:

main.cpp:

int main() {
    cout << "Some other stuff\n";

    double result = foo();

    return 0;
}

script.sh:

sum = 0
num = $1
for((i = 0; i < $num; i++)); do
    result = ./a.out;  #store the result somehow?
    sum = $sum + $result
done
avg = $sum / $num
echo "Average: " $avg

有没有一种简单的方法将程序的结果传回bash脚本中?我读到过使用退出代码的方法,但返回类型是double,所以我不认为这会起作用。从字符串输出中解析值很难处理,因为程序还有其他终端输出。

返回代码必须是整数 - 没有其他的方法。您可以将结果写入特殊文件,然后使用bash读取此文件。 - akhikhl
1
在Unix环境中,在程序之间传输数据的标准方法是通过标准输出和标准输入。打印您的输出。 - David Hammen
一种选择是通过某个因子(如1000)缩放所有输出,转换为int类型并返回,然后在脚本中通过相同的因子进行降尺度处理。 - abiessu
那么,我是不是必须“放弃”程序中的所有其他文本输出,以避免手动解析所需值?(还有一些不是所需值的其他数字结果仍然会打印到控制台供参考) - donnyton
如果您想保留现有的文本输出,请考虑“升级/降级”机制;请注意,缩放和截断会导致自动数据丢失。 - abiessu
2个回答

10

在UNIX系统中,通常会将非关键数据写入stderr,将实际结果写入stdout。这样做的好处是,你可以简单地执行以下操作:

int main() {
    cerr << "This is output that won't be captured." << endl;
    cout << "3.141592" << endl; 
}

并使用命令替换来捕获它:
result=$(./a.out)

一种更丑陋的方法是不需要改变输出,而是写入到另一个文件描述符:

int main() { 
    char* foo = "3.141592\n";
    write(42, foo, strlen(foo));
}

这将让你使用以下代码捕获输出:
result=$(./a.out 42>&1 > /dev/null)

请注意,您的shell脚本存在多个语法错误。尝试使用shellcheck自动解决其中许多问题,并随时发布关于您无法解决的问题的问题。

1
程序还有其他终端输出。 - akhikhl
谢谢!我最终使用命令行参数来在批处理文件输出和详细终端输出之间切换。 - donnyton

6
为什么不将返回值作为数据传递给你的Bash脚本呢?
int main() {
        return 46;
}

以下是输出结果(是bash脚本):
./a.out ; echo $?
46

如果涉及到双精度浮点数,您可以采用以下方法:

#include <iostream>

int main() {
        double res = 46.001;
        std::cout << res << std::endl;
        return 0;
}

并且输出:

a=`./a.out`; echo $a
46.001

很遗憾,这只能适用于8位整数,并且无法处理Donnyton想要返回的双精度数。 - that other guy
从字符串输出中解析值很麻烦,因为程序还有其他终端输出。 - that other guy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接