【问题标题】:Stifling "file or directory not found" messages in popen在 popen 中扼杀“找不到文件或目录”消息
【发布时间】:2012-09-27 13:42:05
【问题描述】:

我正在使用 popen 运行系统脚本,如下所示:

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

如果没有找到脚本,程序继续其愉快的方式。但是,会显示“找不到文件或目录”消息,这似乎是一个错误,即使在我的预期用途中它不是。

有没有办法让这条消息静音,或者我应该在运行这条线之前打电话给ls | grep -i myscript

【问题讨论】:

  • 只是/myscript -q 成功了吗? deviceName 是什么?
  • /myscript -q 不成功,这就是关键:脚本不存在,对我来说这与找不到设备的功能相同,这是一个可以接受的结果,应该'不要让我的程序打印错误信息。

标签: c linux popen


【解决方案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,因此它应该非常便携。 (换句话说,dashbash 和 SunOS 5.10 sh 都可以正常工作。)

由于您需要为任何非标准系统重新编译应用程序,您始终可以编辑宏以省略前缀。 (如果需要,您可以轻松地向Makefile 魔术添加测试以自动省略它,如果您曾经找到这样的系统。)

请注意,我修改了snprintf() 调用中的参数替换。它适用于任何包含单引号的deviceName。在 snprintf() 调用之前,deviceName 中的任何单引号都应替换为字符串 '"'"'

问题?

【讨论】:

  • 这不会在应用程序运行的其余部分关闭错误流,对吗?
  • 不,重定向只影响使用popen() 运行的命令。应用程序可以在之前、期间和之后正常使用stderr;它根本不受此影响。
【解决方案2】:

我不太确定你是否可以扼杀信息。该错误是打印到标准错误流上的标准 Linux 错误。您可以保留 FD '2',它是标准错误的文件描述符。所以也许你可以关闭这个FD。

但是,我必须警告您,这将防止在您的程序的其余部分打印任何错误。

更好的方法是这样做: snprintf(cmd, MAX_PATH, "/myscript -q | grep -i %s 2> dummyfile", deviceName);

这会将错误重定向到您立即删除的虚拟文件。

所以请谨慎行事并决定您想做什么......

干杯, 虚拟网络

【讨论】:

    猜你喜欢
    • 2021-01-04
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多