在C++中與Linux命令行進行交互,通常涉及到執行外部命令并處理其輸出。這可以通過多種方式實現,包括使用標準庫函數、系統調用或者第三方庫。以下是一些常用的方法和技巧:
system()
函數
system()
是一個簡單的調用,可以用來執行shell命令。它的原型在 <cstdlib>
頭文件中定義。#include <cstdlib>
int main() {
int ret = system("ls -l");
return ret;
}
注意:system()
函數會阻塞直到命令執行完畢,并且它不能很好地處理命令的輸出。
popen()
和 pclose()
函數
popen()
函數可以打開一個指向命令的管道,并允許你讀取命令的輸出或向其寫入數據。pclose()
用于關閉這個管道。#include <cstdio>
#include <memory>
#include <stdexcept>
#include <string>
std::string exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe) throw std::runtime_error("popen() failed!");
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
int main() {
std::string output = exec("ls -l");
std::cout << output;
return 0;
}
fork()
和 exec()
系列函數
這些函數提供了更細粒度的控制,允許你創建新的進程并替換它們的內存空間來運行新的程序。#include <unistd.h>
#include <sys/wait.h>
#include <iostream>
int main() {
pid_t pid = fork();
if (pid == 0) {
// 子進程
execl("/bin/ls", "ls", "-l", NULL);
// 如果execl返回,則表示失敗
std::cerr << "Error executing ls\n";
return 1;
} else if (pid > 0) {
// 父進程
int status;
waitpid(pid, &status, 0); // 等待子進程結束
} else {
// fork失敗
std::cerr << "Error creating child process\n";
return 1;
}
return 0;
}
#include <boost/process.hpp>
#include <iostream>
#include <string>
namespace bp = boost::process;
int main() {
std::string line;
bp::ipstream pipe_stream;
bp::child c("ls -l", bp::std_out > pipe_stream);
while (c.running() && std::getline(pipe_stream, line) && !line.empty())
std::cout << line << std::endl;
c.wait();
return 0;
}
在使用這些方法時,請確??紤]到安全性,特別是當執行的命令包含用戶輸入時,以避免注入攻擊。此外,錯誤處理在這些示例中被簡化了,實際應用中應該更加健壯。