我正试图在计算机集群上运行下面的简单c++程序(运行Linux,CentOS 6)。
#include <iostream>
#include <fstream>
int main(int argc, char *argv[]) {
std::ofstream file;
file.open("/dev/stdout");
file << "Hello, worldn";
file.close();
return 0;
}
当我编译(使用g++ test.cpp
)并在head节点上运行程序时,无论我是否让输出转到将其重定向到文件的终端,它都会像我预期的那样工作。也就是说,
$ ./a.out > myfile.txt
生成一个文件myfile.txt
,其中包含行"Hello,world"(我使用的是bash)。如果我在任何一个执行节点上运行它,并让输出进入终端,它就可以正常工作;但是,如果我试图将输出重定向到一个文件,该文件总是空的。
我知道这不是用C++编写helloworld程序的"标准"方式。事实上,我在第三方程序中遇到了困难,该程序试图使用需要文件名的库将二进制数据写入标准输出。在试图减少发布的代码时,我发现上面是最简单的代码,它再现了我在更大的程序中看到的问题。
我不是一个经验丰富的C++程序员,所以不知道上面的例子应该还是不应该工作,但事实上,它在一些计算机上可以工作,正如我所期望的,但在其他计算机上却不能工作,这让我很困惑。我也不确定这是否与C++代码、bash或系统配置有关。我问过的人似乎也同样困惑,甚至无法建议从哪里开始寻找。
我已经用其他语言创建了简单的helloworld程序,这些程序在执行节点上都能正常工作,所以我认为这是C++特有的。
有人能向我解释,或者帮助我确定为什么我在运行相同操作系统(并且应该配置相同)的机器上观察到不同的行为吗?C++中有没有一种(首选)方法可以获得需要文件名才能写入stdout的库函数?
我环顾四周,发现可能是也可能不是您正在使用的程序:uuencode。如果不是这样,就忽略整个答案。这个程序看起来很难使用,所以我将概述我认为合理的使用方法:
将任何内容作为"输出文件名"提供给uuencode
uuencode mybinaryfile anything > mytextfile
然后将生成的"mytextfile"传输到运行的新系统
uudecode mytextfile -o mynewbinaryfile
它产生了"mynewbinaryfile"。同样,这个程序的设计(尤其是我作为"任何东西"传入的参数)都不太好,而且在将二进制文件从一台机器移动到另一台机器时,存在字节序和类型大小的问题,而这个程序忽略了这些问题。我建议远离它。
至于解释,uudecode试图写入/dev/stdout,而在集群和HPC机器上,所有像/dev/stdout这样的常见适应都不再是它们看起来的样子。
很可能问题出在fstream.open()
的mode
参数上。
顺便说一句,这是一种相当奇怪的执行配置输出的方式。。。