views:

196

answers:

1

Hi all,

I've got a GUI C++ program that takes a shell command from the user, calls forkpty() and execvp() to execute that command in a child process, while the parent (GUI) process reads the child process's stdout/stderr output and displays it in the GUI.

This all works nicely (under Linux and MacOS/X). For example, if the user enters "ls -l /foo", the GUI will display the contents of the /foo folder.

However, bash niceties like output redirection aren't handled. For example, if the user enters "echo bar > /foo/bar.txt", the child process will output the text "bar > /foo/bar.txt", instead of writing the text "bar" to the file "/foo/bar.txt".

Presumably this is because execvp() is running the executable command "echo" directly, instead of running /bin/bash and handing it the user's command to massage/preprocess.

My question is, what is the correct child process invocation to use, in order to make the system behave exactly as if the user had typed in his string at the bash prompt? I tried wrapping the user's command with a /bin/bash invocation, like this: /bin/bash -c the_string_the_user_entered, but that didn't seem to work. Any hints?

ps Just calling system() isn't a good option, since it would cause my GUI to block until the child process exits, and some child processes may not exit for a long time (if ever!)

+1  A: 

If you want the shell to do the I/O redirection, you need to invoke the shell so it does the I/O redirection.

char *args[4];
args[0] = "bash";
args[1] = "-c";
args[2] = ...string containing command line with I/O redirection...;
args[4] = 0;

execv("/bin/bash", args);

Note the change from execvp() to execv(); you know where the shell is - at least, I gave it an absolute path - so the path-search is not relevant any more.

Jonathan Leffler