I'm trying to call a shell script from C++ with custom input. What I could do is:
void dostuff(string s) {
system("echo " + s + " | myscript.sh");
...
}
Of course, escaping s is quite difficult. Is there a way that I can use s as stdin for myscript.sh? Ie, something like this:
void dostuff(string s) {
FILE *out = stringToFile(s);
system("myscript.sh", out);
}
A simple test to reassign stdin and restore it after the
system
call:Works out nicely. I tested it with a simple
dummy.sh
script like this:Note the last line dumps standard input to standard output, so you could test it like
and expect the following output:
Use
popen
:You'll need to add error checking to make this robust.
Note that I prefer a
const char*
, since it is more flexible (works with things other thanstd::string
) and matches what's going on inside. If you really preferstd::string
, do it like so:Also note that the 4096-byte buffer was chosen because it matches the page size on most systems. This isn't necessarily the most efficient approach, but it'll be fine for most purposes. I've found 32 KiB to be a sweet spot in my own unscientific tests on a laptop, so you might want to play around, but if you are serious about efficiency, you'll want to switch to asynchronous I/O, and start readn+1 immediately after initiating writen.