Linux command executed from C code system() function giving different result as compared to when executed from Terminal

236 views Asked by At

I am running a bunch of Linux commands from my C code using system() function. The result of running these commands from C code differs from the result when these commands are run from terminal. Example:

std::string name("\\pot\ ");
std::stringstream extractInfoCmd;
extractInfoCmd<<"find . -name \"*.info\" | xargs grep -E \"^PART|^"<<name.c_str()<<"\" >> information.rpt";
std::string extractInfoCmdStr = extractInfoCmd.str();
printf("\n##DEBUG Command: %s\n", extractInfoCmdStr.c_str());
system(extractInfoCmdStr.c_str());

If my input file contains these 2 lines:

PART: 6
\pot : f

Now if I execute the same command(received from DEBUG log above) from terminal, I got both lines. But if I execute the same command from C system() function, I get only first line, not the second line:

PART: 6

I have been debugging this since long and the cause of it is not striking to me.

1

There are 1 answers

1
Daniel Pryden On

The backslashes in the name string are getting interpreted by your compiler, and then you're using that string to build the extractInfoCmd string, which you pass to the shell (/bin/sh) which tries to interpret them again. So the actual string that gets passed to the grep process isn't the one you intend.

Probably the best way to fix this is to avoid using system and instead use something like execlp, where you can pass each argument separately.

There's also no need to use a pipeline to pass information from find to grep, you can do that with find itself:

find . -name '*.info' -exec grep -E '^PART|^\\pot\ ' {} \;

Or, directly in C:

execlp(
    "/usr/bin/find",
    ".",
    "-name",
    "*.info",
    "-exec",
    "grep",
    "-E",
    "^PART|^\\\\pot\\ ",
    "{}",
    ";",
    NULL);

Rather than piping the output to a file using the shell, you can just use pipe in your process to get a pipe to find's standard output directly, which you can then read from.