メインコンテンツに移動

コマンドを実行

コマンドを実行

古来より, C言語ではsystem()関数でコマンド(ls とか dateとか)が実行でき, その出力をなんとか取得することができました.2019年現在も,C++コードで,なにかOSのコマンドを実行したいとGoogleに尋ねれば, system()とお友達を使えということになっています.ですが, これはコマンドがうまくいったか?コマンドがどんな出力を出したか?が不明になります.それらを取得するのは素人には不可能です.

Boost.Processでは,素晴らしく簡単です.例を示しておきましょう.

     auto cmd=boost::process::search_path("ls");//lsを実行
     std::vector<std::string> args;                       //引数を作りましょう
     args.push_back("-l");     args.push_back("../POKE");
     boost::process::ipstream std_out, std_err;          //結果をゲットするストリームを準備
     auto child=boost::process::child(cmd,
          boost::process::args(args),
          boost::process::std_out > std_out,
          boost::process::std_err > std_err );

これで現在のプロセスが分裂(Cでいうところのfork)して, 2スレッド並列実行が始まります. 第一のスレッドではあなたのプログラムが実行され,第二のスレッド(child)では,lsコマンドが実行され始めます. 必ず,その終了を待つ必要があります:

     child.wait();//プロセスが終わるのを待つ  

コマンドが完了したので, エラーの有無を調べたり, 出力を調べたりできます:

     std::vector<std::string> sout,serr; //標準出力とエラー出力を格納しよう
     std::string str;
     while (std::getline(std_out,str)) sout.push_back(str);
     while (std::getline(std_err,str)) serr.push_back(str);
     auto result=child.exit_code();
     for(auto& s:sout) std::cout << "いただきました[ " << s << " ]" << std::endl;
     for(auto& s:serr) std::cout << "エラー出力    [ " << s << " ]" << std::endl; 
     if (result) std::cout << "エラーしとるわボケ" << std::endl;

child()の他にも, launch()とかいろいろあるんですが・・・そこは Boost.ProcessでGoogleしてください.