【发布时间】:2014-04-16 14:57:51
【问题描述】:
我正在无限循环中执行一个 shell 脚本。脚本旨在获取连接的设备。但是运行一段时间后,会在显示错误信息pipe call failed后停止执行。
这是我收到此错误的行
arp -n -i eth1 | grep "?" | awk '{print $4}' > out.txt
在将此输出重定向到文件时我做错了什么吗?有没有办法在 shell 脚本中处理文件描述符?
编辑:这是我的脚本
HOME_NETWORK_INTERFACE=eth1
echo "Generating list of MoCA device MACs..."
if [ $# -lt 1 ]; then
echo "Error! Insufficient arguments. Format is $0 <output file path>"
exit 1
fi
arp -n -i $HOME_NETWORK_INTERFACE | grep "?" | awk '{print $4}' > $1
echo "Done"
编辑:
我发现这个问题是由于在 cpp 应用程序中使用了“system”命令造成的。如果使用“系统”执行此脚本,例如 1000 次,我将收到此错误。有人对此有任何想法吗?提前致谢
【问题讨论】:
-
我不认为
grep会为此引发语法错误,但您可能想要修复 [grep(partmaps.org/era/unix/award.html#grep) 的无用使用;arp | awk '/\?/{ print $4 }' -
pipe call failed听起来更像是内部系统错误,而不是与您的脚本直接相关的错误。不过,您可以发布更多上下文脚本吗?您发布的行看起来不错。 -
通过调用
system(),您正在分叉一个子进程。每当一个子进程被分叉时,系统都会尝试将父内存复制到子内存。如果你尝试 fork 一个子进程 1000 次,内存可能还没有释放到系统,因此系统会认为父进程有更大的内存,它实际上正在使用,你正在耗尽内存根据记忆会计师。您可以设置限制并将内存过度使用设置为 2。但是过度使用并不是一个好主意。 -
system() 执行命令解释器,即 shell,它比直接 fork/exec 慢。也许您可以看看是否可以避免使用 system() 并尝试使用 fork/exec 以获得更多控制权(例如,清理 fork/exec 调用之间的内存。
-
当您说“cpp 应用程序”时,您是指用 C++ 编写的应用程序吗?你的意思是你的脚本是从你的应用程序中运行的吗?我估计“管道调用失败”的最可能原因是您打开了太多文件描述符;您不会在可能的情况下关闭某些文件(或管道或套接字)。错误是来自 shell 脚本本身,还是来自通过
system()运行它的 C++ 程序?当system()调用返回时,孩子已经死了;它的所有文件描述符都已关闭。应用程序应该没有问题。您是否正确设置了 FD_CLOEXEC?