我正在infinte循环中执行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”命令。如果使用“system”执行此脚本,比如1000次,我将收到此错误。有没有人对此有任何想法?提前致谢
答案 0 :(得分:2)
我的脚本没有看到任何明显的问题;错误消息“听起来像' 系统资源 问题(系统之间的这些值可能会有很大差异。)一些建议:
在涉及特殊字符时考虑使用'fgrep',你需要否定可能的shell变量munging(不要认为这是一个因素,但以防万一......)
使用 ulimit -a
你可能'消费'比允许的更开放的文件(猜测)或者可能是'系统'有问题(而不是'用户进程'); “真正的”问题可能是同时运行的其他一些进程正在消耗资源。
如果您的系统/用户'限制'没问题,并且由于您声明这是一个'无限循环',那么我猜你会产生多个进程,而不是只运行一个进程。一旦达到管道或文件相关资源的“硬限制”,脚本就会失败,并且您会收到“系统错误”。
$ ulimit -a | awk'{printf“%3d |%s \ n”,NR,$ 0}'
1 |核心文件大小(块,-c)0
2 |数据seg大小(千字节,-d)无限制 3 |调度优先级(-e)0
4 |文件大小(块,-f)无限制 5 |待处理信号(-i)46232
6 |最大锁定内存(千字节,-l)64
7 |最大内存大小(千字节,-m)无限制 8 |打开文件(-n)1024
9 |管道大小(512字节,-p)8
10 | POSIX消息队列(字节,-q)819200
11 |实时优先级(-r)0
12 |堆栈大小(千字节,-s)10240
13 | cpu时间(秒,-t)无限制 14 |最大用户进程(-u)1024
15 |虚拟内存(千字节,-v)无限制 16 |文件锁(-x)无限
答案 1 :(得分:2)
错误消息&#34;管道调用失败&#34;意味着没有更多的可用内存来分配。 根据Dale的建议,使用 ulimit -a 检查系统的限制,并验证以何种方式调用 system 命令:顺序或并行。
从内核2.6.11开始,管道的大小为64KB。而且,system()命令通过调用 / bin / sh -c命令来执行命令,并在命令完成后返回。调用系统命令1000次效率不高,所以我的建议是在脚本中添加 while 循环以避免性能不佳(可以提供迭代次数)作为第二个论点)。
最后,如果要将其作为可执行文件运行,最好添加一个shebang(#!/ bin / sh )作为脚本的第一行。这不是绝对必要的,因为如果缺少shebang,则使用默认shell(例如 / bin / sh )。
#!/bin/sh
HOME_NETWORK_INTERFACE=eth0
echo "Generating list of MoCA device MACs..."
if [ $# -lt 1 ]; then
echo "Error! Insufficient arguments. Format is $0 <output file path>"
exit 1
fi
X=0
while [ $X -lt $2 ]
do
arp -n -i $HOME_NETWORK_INTERFACE | grep "?" | awk '{print $4}' > $1
X=`expr $X + 1`
done
echo "Done"
答案 2 :(得分:2)
“alvits”确切地指出了使用system命令的问题。通常我们尝试实现等效的“C”代码,而不是使用系统命令,以避免内存峰值。
您似乎正在使用while循环进入C ++代码并调用此脚本。试试你是否可以在while循环中运行脚本(只产生一个系统调用),将o / p重定向到一个文件并连续读取文件以获得所需的结果。
答案 3 :(得分:0)
最后我发现了这个问题。我在我的应用程序中使用套接字通信。一些套接字如何没有正确关闭。所以一段时间之后文件描述符会耗尽导致问题“管道调用失败”,因为管道也使用描述符。