Say in C, I want to call execvp()
on any string command. Command can just be:
char command[] = "ls -l";
char command[] = "rm *.txt";
char command[] = "cat makefile";
I want to put this command variable inside execvp()
. So the exec()
flavored function can just run with any kind of arbitrary command.
How can I do that? Thanks.
NOTE: system()
is not allowed.
If you have to call execvp()
, then you will need to split up those strings into an executable name and an array of arguments (the first being the "name" of the program and the last being a NULL pointer).
That means something like:
char cmd1[] = "ls"; char *args1[] = {"ls", "-l", NULL};
char cmd1[] = "rm"; char *args1[] = {"rm", "*.txt", NULL}; // but see
// globbing below.
char cmd1[] = "cat"; char *args1[] = {"cat", "makefile", NULL};
This is a non-trivial exercise, especially if you want to allow for quoting, globbing, escaping and so forth.
Quoting means you'll have to be careful with commands like:
rm "file with spaces.txt"
in that you can't simply break on the spaces - you'll have to interpret items in the command much the same as the shell does. Simplistic breaking on spaces would give you a command with three arguments for that string above, rather than the correct one.
By globbing, I mean you'll almost certainly have problems with something like *.txt
since it's typically the shell which expands these arguments. Passing that directly to execvp()
will result in a single argument of literally *.txt
rather than many arguments matching all the text files in your current directory.
Quoting means that you'll have to handle things like:
ls -l "file with spaces and \" quote in it"
which will further complicate your parser.
Don't get me wrong, it can be done, but it's probably a damn sight easier just using system()
.
If you're still thinking of going the execvp()
route, you'll have to:
execvp()
with the parameters being first element in that array and the address of the array.