A C++ high level library for running shell processes
A no nonsense library for writing shell commands in C++.
Writing shell commands in modern C++ is deceptively hard. There are many C++ subprocessing libraries out there, but none of them just work. The aim of this library is to allow you to write shell commands in C++ almost as if you were writing them in shell.
Full documentation for subprocess
is available here.
Note: Windows is not currently supported.
It works exactly how you would expect it to work. Drop subprocess.hpp
in your project, include it, and start working!
#include <subprocess/subprocess.hpp>
using namespace subprocess::literals;
int main()
{
std::string cmd_output;
("ls -l"_cmd | "awk 'NR>1{print $3}'"_cmd | "sort"_cmd | "uniq"_cmd > cmd_output).run();
// Use cmd_output in the program
}
Instead of trying to emulate the subprocess interface from libraries in other languages, this library aims to use (and abuse) C++ operator overloading to achieve a shell-like syntax for writing shell commands.
subprocess
follows these design goals:
subprocess
and unix shell. In case such differences arise, they should be clearly documented.subprocess.hpp
and requires no adjustments to compiler flags or project settings. It has no dependencies, subprojects or dependencies on any build system.You can write shell commands using the subprocess::command
class and use the resulting object to pipe I/O from/to standard streams, files, and variables.
Examples:
// Running a command
subprocess::command cmd{"touch" + file_path}.run();
// Piping the output of a command to another command
cmd | "uniq"_cmd;
You can use operator<
to redirect stdin to the command object.
Examples:
// Reading input from a file
cmd < std::filesystem::path{file_name};
cmd < "file_name";
// Reading input from a variable
std::string input{"abc"};
cmd < input;
// Reading from an already created fd
cmd < subprocess::file_descriptor{fd_no};
The following operators are available for redirecting stdout:
operator>
: Truncates the file and writes outputoperator>>
: Appends output to file if it already exists, otherwise creates one.Examples:
// Redirecting stdout to stderr
cmd > subprocess::err;
// Redirecting stdout to a file
cmd > std::filesystem::path{file_name};
// or appending to a file
cmd >> std::filesystem::path{file_name};
// Capturing stdout in a variable
std::string var_name;
cmd > var_name;
The following operators are available for redirecting stdout:
operator>=
: Truncates the file and writes stderroperator>>=
: Appends stderr to file if it already exists, otherwise creates one.Examples:
// Redirecting stderr to stdout
cmd >= subprocess::out;
// Redirecting stderr to a file
cmd >= std::filesystem::path{file_name};
// or appending to a file
cmd >>= std::filesystem::path{file_name};
// Capturing stderr in a variable
std::string var_name;
cmd >= var_name;
This is a header only library. So developer can just copy-paste its content into their project without any configuration.
For those who want to manage their dependencies using CMake FetchContent, this can be used:
include(FetchContent)
FetchContent_Declare(subprocess
GIT_REPOSITORY https://github.com/rajatjain1997/subprocess
GIT_TAG v0.1.1
GIT_PROGRESS TRUE
)
target_link_libraries(my_application subprocess::subprocess)
I would love your feedback! If you find any issues, feel free to log them.