簡體   English   中英

C++ 在同一個 shell 實例上運行 shell 命令

[英]C++ Run a shell command on the same shell instance

所以正如標題所說,我想在 C++ 中的同一個 shell 進程/實例上運行一個 shell 命令並與之通信,我該怎么做? 我已經查找了每個角落,但找不到合適/直截了當的答案。 我不是 C++ 霸主,我的回答可能很愚蠢。 現在我可以在unix上使用 fork/exec 的組合,但我在 Windows 上。 如果有跨平台解決方案,請在下方提及。 提前致謝。

偽代碼:

SHELL shell = make_shell();
shell.run("cd desktop");
shell.run("dir");
print(shell.stdout)

C++ 中的標准庫沒有提供一種方法來做你想做的事。 但是,您可以使用第三方庫,例如boost::process ,這將使您的程序和子進程之間的通信部分非常可移植。 如果你想執行內置的 shell 命令,或者使用 shell 的命令,你仍然需要處理不同平台上使用的 shell 的差異。

boost::process庫包含許多不同的創建子進程並與子進程通信的方式( 參考),包括同步和異步,因此請瀏覽參考頁面以了解它可以做什么。

這是一個簡單的示例,它使用boost::process::system在目錄desktop中運行命令dir並收集該命令的輸出。 使用 shell(通常應該避免使用),而是使用boost::process::search_path來查找命令(在您的PATH中)並直接執行命令而不涉及 shell:

#include <boost/process.hpp>
#include <boost/process/start_dir.hpp>

#include <iostream>
#include <string>

int main() {
    namespace bp = ::boost::process;

    bp::ipstream out;
    bp::ipstream err;
    bp::system(bp::search_path("dir"),
               bp::start_dir = "./desktop",
               bp::std_out > out,           // collect stdout in out
               bp::std_err > err,           // collect stderr in err
               bp::std_in < stdin);         // for commands reading from stdin

    // display what was collected on stdout and stderr:
    std::string line;
    std::cout << "stdout capture:\n";
    while(std::getline(out, line)) {
        std::cout << '[' << line << "]\n";
    }

    std::cout << "\nstderr capture:\n";
    while(std::getline(err, line)) {
        std::cout << '[' << line << "]\n";
    }
}

注意:您需要鏈接boost_filesystemboost_atomic使此示例正常工作。

Linux:執行 Windows:CreateProcessA

編寫 ifdefs 以根據平台進行切換。

我找到了這個答案: https ://stackoverflow.com/a/57096619/9282847。
它似乎是唯一既標准又可移植的方法(假設實現支持std::filesystem )。

喜歡:

#include <filesystem>
#include <iostream>

int main() {
  namespace fs = std::filesystem;

  const auto kDesktopPath = fs::path("~/Desktop"); // portable filepath
  fs::current_path(kDesktopPath); // set CWD (This will throw on compiler explorer)

  auto dir_it = fs::recursive_directory_iterator{ fs::current_path() }; 
  for (auto& f: dir_it) {
    std::cout.put('\n') << f;
  }

}

編譯器資源管理器上的實時示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM