dkb
dkb

Reputation: 561

Stifling "file or directory not found" messages in popen

I'm using popen to run a system script, like so:

snprintf(cmd, MAX_PATH, "/myscript -q | grep -i %s", deviceName);
FILE *res = popen(cmd, "r");

If the script is not found, the program carries on its merry way. However, a "file or directory not found" message is displayed, which seems like an error even though in my intended usage it isn't.

Is there a way to silence this message, or should I just call ls | grep -i myscript before running this line?

Upvotes: 0

Views: 1067

Answers (2)

Nominal Animal
Nominal Animal

Reputation: 39316

Assuming your /bin/sh is a POSIX shell, or a reasonably recent Bourne shell variant, you can redirect standard output within the command before executing the actual command. You only need to prepend exec 2>/dev/null ; before the command you wish to execute.

Here is how I'd personally do this:

/* Shell syntax for redirecting standard error to /dev/null, to
 * silence any errors. If /bin/sh does not support this, you can
 * simply replace it with an empty string.
*/
#define  POPEN_STDERR_NULL "exec 2>/dev/null ;"

...

snprintf(cmd, MAX_PATH, POPEN_STDERR_NULL "/myscript -q | grep -i -e '%s'", deviceName);
FILE *res = popen(cmd, "r");

The popen() command uses /bin/sh internally to run the specified command. The above works for all /bin/sh variants I can test, including Linux and SunOS 5.10, so it should be quite portable. (In other words, dash, bash, and SunOS 5.10 sh all work fine with it.)

Since you'll need to recompile the application for any nonstandard systems, you can always edit the macro to omit the prefix. (You can easily add a test to Makefile magic to automatically omit it if necessary, if you ever find such a system.)

Note that I modified the parameter substitution in the snprintf() call. It will work for any deviceName that does not contain a single quote. Any single quotes in deviceName should be replaced with the string '"'"' before the snprintf() call.

Questions?

Upvotes: 2

VSN
VSN

Reputation: 416

I'm not too sure if you can stifle the message. The error is a standard Linux error which is printed onto the standard error stream. You can keep FD '2' which is the file descriptor for Standard error. So maybe you can close this FD.

However, I must warn you that this will prevent any errors from being printed for the rest of your program.

A better way would be to do this: snprintf(cmd, MAX_PATH, "/myscript -q | grep -i %s 2> dummyfile", deviceName);

This will redirect the error to a dummy file which you delete immediately.

So exercise caution and decide what you would like to do...

Cheers, VSN

Upvotes: 0

Related Questions