运行shell脚本时出错:“管道调用失败”

时间:2014-03-12 12:50:15

标签: c++ c linux shell sh

我正在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次,我将收到此错误。有没有人对此有任何想法?提前致谢

4 个答案:

答案 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)

最后我发现了这个问题。我在我的应用程序中使用套接字通信。一些套接字如何没有正确关闭。所以一段时间之后文件描述符会耗尽导致问题“管道调用失败”,因为管道也使用描述符。

相关问题