简体   繁体   English

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

[英]Error while running a shell script : “pipe call failed”

I am executing a shell script in an infinte loop. 我正在无限循环中执行Shell脚本。 Script is meant to get the connected devices. 脚本旨在获取连接的设备。 But when it runs for some time, it will stop executing after displaying an error message pipe call failed . 但是当它运行一段时间后,它将在显示错误消息pipe call failed之后停止执行。

This is the line where I am getting this error 这是我收到此错误的行

arp -n -i eth1 | grep "?" | awk '{print $4}' > out.txt

Am I doing anything wrong in redirecting this output to a file? 将输出重定向到文件时,我做错什么了吗? Is there a way to handle file descriptors in a shell script? 有没有办法在Shell脚本中处理文件描述符?

EDIT: Here is my script 编辑:这是我的脚本

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"

EDIT : 编辑:

I found that this issue is due to the usage of "system" command in cpp application. 我发现此问题是由于在cpp应用程序中使用了“ system”命令。 If this script is executed using "system", say 1000 times, i will get this error. 如果使用“系统”执行此脚本,比如说执行1000次,我将收到此错误。 Does any one have any idea about this? 有人对此有任何想法吗? Thanks in advance 提前致谢

I don't see any obvious issues with your script; 我看不到您的脚本有任何明显的问题; the error messages does 'sound like' a system resource problem (and these values may vary considerably between systems.) Some suggestions: 错误消息确实听起来像是系统资源问题(并且这些值在系统之间可能会有很大差异。)一些建议:

  • Consider using 'fgrep' when special characters are involved and you need to negate possible shell variable munging (don't think that's a factor here, but just in case...) 当涉及特殊字符时,请考虑使用“ fgrep”,并且您需要否定可能的shell变量修改(不要以为这是一个因素,但以防万一...)

  • Check the 'limits' for the user/process you are running using ulimit -a 使用ulimit -a检查您正在运行的用户/进程的“限制”

  • you could be 'consuming' more open files (guessing) than allowed OR it could be that the 'system' is having the issue (instead of the 'user process'); 您可能“消耗”了比允许的更多的打开文件(猜测),或者可能是“系统”出现了问题(而不是“用户进程”); the 'real' problem could be some other process running at the same time is consuming the resource. “实际”问题可能是同时运行的其他某些进程正在消耗资源。

  • If your system/user 'limits' are ok and Since you state that this is an 'infinite loop' then I will guess that you are spawning multiple processes instead of running only one. 如果您的系统/用户的“限制”没有问题,并且由于您声明这是一个“无限循环”,那么我猜您正在生成多个进程而不是仅运行一个进程。 Once you reach the 'hard limit' for pipe or file-related resources the script fails and you get a 'system error'. 一旦达到管道文件相关资源的“硬限制”,脚本就会失败,并且会出现“系统错误”。

    $ ulimit -a | $ ulimit -a | awk '{printf "%3d | %s\\n", NR, $0}' awk'{printf“%3d |%s \\ n”,NR,$ 0}'

1 | 1 | core file size (blocks, -c) 0 核心文件大小(块,-c)0
2 | 2 | data seg size (kbytes, -d) unlimited 数据段大小(千字节,-d)无限
3 | 3 | scheduling priority (-e) 0 调度优先级(-e)0
4 | 4 | file size (blocks, -f) unlimited 文件大小(块,-f)无限
5 | 5 | pending signals (-i) 46232 待处理信号(-i)46232
6 | 6 | max locked memory (kbytes, -l) 64 最大锁定内存(千字节,-l)64
7 | 7 | max memory size (kbytes, -m) unlimited 最大内存大小(千字节,-m)无限制
8 | 8 | open files (-n) 1024 打开文件(-n)1024
9 | 9 | pipe size (512 bytes, -p) 8 管道大小(512字节,-p)8
10 | 10 | POSIX message queues (bytes, -q) 819200 POSIX消息队列(字节,-q)819200
11 | 11 | real-time priority (-r) 0 实时优先级(-r)0
12 | 12 | stack size (kbytes, -s) 10240 堆栈大小(KB,-s)10240
13 | 13 | cpu time (seconds, -t) unlimited cpu时间(秒,-t)无限制
14 | 14 | max user processes (-u) 1024 最大用户进程(-u)1024
15 | 15 | virtual memory (kbytes, -v) unlimited 虚拟内存(千字节,-v)无限
16 | 16 | file locks (-x) unlimited 文件锁(-x)无限

The error message "pipe call failed" means that there is no more free memory to allocate. 错误消息“管道调用失败”意味着没有更多的可用内存可分配。 As suggested by Dale, check the limits of your system using ulimit -a and verify in which way the system command is called: sequentially or in parallel. 根据Dale的建议,使用ulimit -a检查系统的限制,并验证以哪种方式调用系统命令:顺序还是并行。

Pipes have a size of 64KB starting form the kernel 2.6.11. 从内核2.6.11开始,管道的大小为64KB。 Moreover, the system() command executes a command by calling /bin/sh -c command and returns after the command has been completed. 此外,system()命令通过调用/ bin / sh -c命令执行命令,并在命令完成后返回。 Is not very efficient to call the system command 1000 times, so my advice is to add a while cycle inside your script to avoid weak performance (you can provide the number of iterations as a second argument). 调用系统命令1000次不是很有效,因此我的建议是在脚本内部添加一个while循环以避免性能下降(您可以将迭代次数作为第二个参数来提供)。

Finally, it is a good practice to add a shebang ( #!/bin/sh ) as the first line of the script if it is intended to be run as an executable. 最后,如果打算以可执行文件形式运行脚本,则最好在脚本的第一行添加shebang( #!/ bin / sh )。 This is not strictly necessary, because if the shebang is missing, the default shell (eg /bin/sh ) is used. 这不是严格必要的,因为如果缺少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"

"alvits" has exactly pointed out the issue with using system command. “ alvits”已经明确指出了使用系统命令的问题。 Usually we try to implement the equivalent "C" code rather than using system command so as to avoid memory spikes. 通常,我们尝试实现等效的“ C”代码,而不是使用系统命令,以避免内存高峰。

It seems that you are using a while loop into you C++ code and calling this script. 看来您正在使用while循环进入C ++代码并调用此脚本。 Just try if you can run the script in while loop (resulting into only a single system call), redirect the o/p to a file and the read the file continuously for the desired result. 请尝试是否可以在while循环中运行脚本(仅导致单个系统调用),将o / p重定向到文件,然后连续读取文件以获得所需的结果。

Finally i found the issue. 终于我找到了问题。 I am using socket communication in my application. 我在我的应用程序中使用套接字通信。 Some how some sockets were not closing properly.so after some time file descriptors will exhaust which is leading to the issue "pipe call failed" because pipe also uses descriptors. 有些套接字无法正常关闭的原因。一段时间后,文件描述符将耗尽,这导致出现“管道调用失败”的问题,因为管道也使用了描述符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM