我正在使用popen来运行系统脚本,如下所示:
snprintf(cmd, MAX_PATH, "/myscript -q | grep -i %s", deviceName);
FILE *res = popen(cmd, "r");
如果找不到脚本,程序会以愉快的方式继续运行。但是,会显示“未找到文件或目录”消息,即使在我的预期用途中也不是这样,这似乎是一个错误。
有没有办法让这条消息无声,或者我应该在运行此行之前调用ls | grep -i myscript
?
答案 0 :(得分:1)
假设您的/bin/sh
是一个POSIX shell,或者是一个合理的Bourne shell变体,您可以在执行实际命令之前在命令中重定向标准输出。您只需要在要执行的命令之前添加exec 2>/dev/null ;
。
以下是我个人如何做到这一点:
/* 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");
popen()
命令在内部使用/bin/sh
来运行指定的命令。以上适用于我可以测试的所有/bin/sh
变体,包括Linux和SunOS 5.10,所以它应该是非常便携的。 (换句话说,dash
,bash
和SunOS 5.10 sh
都可以正常使用。)
由于您需要为任何非标准系统重新编译应用程序,因此您始终可以编辑宏以省略前缀。 (您可以轻松地将测试添加到Makefile
魔法,以便在必要时自动省略它,如果您找到了这样的系统。)
请注意,我在snprintf()
调用中修改了参数替换。它适用于不包含单引号的任何deviceName
。在deviceName
调用之前,'"'"'
中的任何单引号都应替换为字符串snprintf()
。
有问题吗?
答案 1 :(得分:0)
我不太确定你是否可以扼杀这个消息。该错误是标准Linux错误,打印在标准错误流上。您可以保留FD'2',它是标准错误的文件描述符。所以也许你可以关闭这个FD。
但是,我必须警告您,这样可以防止为您的程序的其余部分打印任何错误。
更好的方法是这样做: snprintf(cmd,MAX_PATH,“/ myscript -q | grep -i%s 2> dummyfile”,deviceName);
这会将错误重定向到您立即删除的虚拟文件。
因此请谨慎行事并决定您想做什么......
干杯, VSN