症状很简单。例如:
ls | grep a | grep b | grep c | grep d
Run Code Online (Sandbox Code Playgroud)
投掷
-bash: child setpgid (8948 to 8943): Operation not permitted
-bash: child setpgid (8950 to 8943): Operation not permitted
-bash: child setpgid (8952 to 8943): Operation not permitted
-bash: child setpgid (8953 to 8943): Operation not permitted
-bash: child setpgid (8954 to 8943): Operation not permitted
-bash: child setpgid (8955 to 8943): Operation not permitted
-bash: child setpgid (8962 to 8957): Operation not permitted
-bash: child setpgid (8964 to 8957): Operation not permitted
-bash: child setpgid (8966 to 8957): Operation not permitted
-bash: child setpgid (8967 to 8957): Operation not permitted
-bash: child setpgid (8968 to 8957): Operation not permitted
-bash: child setpgid (8969 to 8957): Operation not permitted
-bash: child setpgid (8976 to 8971): Operation not permitted
-bash: child setpgid (8978 to 8971): Operation not permitted
-bash: child setpgid (8980 to 8971): Operation not permitted
-bash: child setpgid (8981 to 8971): Operation not permitted
-bash: child setpgid (8982 to 8971): Operation not permitted
-bash: child setpgid (8983 to 8971): Operation not permitted
-bash: child setpgid (8990 to 8985): Operation not permitted
-bash: child setpgid (8992 to 8985): Operation not permitted
-bash: child setpgid (8994 to 8985): Operation not permitted
-bash: child setpgid (8995 to 8985): Operation not permitted
-bash: child setpgid (8996 to 8985): Operation not permitted
-bash: child setpgid (8997 to 8985): Operation not permitted
Run Code Online (Sandbox Code Playgroud)
grep使用的 s 和管道的数量并不重要。有时ls | grep a也会抛出错误。
AFAIK,lsanadgrep不需要 root 权限。因此,我想知道如何解决这个问题。
当前机器是Cent OS 5(内核2.6.18)。如果您需要更详细的信息,请告诉我。
添加:ls和的踪迹grep
type ls
ls is aliased to `ls -hF --color=auto'
which ls
/bin/ls
type grep
grep is /bin/grep
which grep
/bin/grep
Run Code Online (Sandbox Code Playgroud)
已添加 2
这时我发现这不仅仅限于ls和grep。似乎它适用于所有使用管道的命令。例如,echo 'Hello' | tee outfile抛出相同的错误。
添加 3:响应@Argonauts'
由于日志太长,请参考https://gist.github.com/anonymous/5459fa0322d178f85b0cd2d5ee2add53。
简而言之,
ulimit -a
type log说-bash: type: log: not found:好的trap -ptrap -- 'history_to_syslog' DEBUG: 。会引起问题吗?这里有一些可以尝试的方法,最好的情况下应该有助于解决您的问题,最坏的情况下应该有助于找出问题“不”是什么。在某些情况下,您可能需要组合这些步骤(例如 strace 和“尝试清除环境”)。
使用以下命令检查您的 shell 中允许的进程数或管道最大大小是否设置了异常低的限制:
ulimit -a
如果可以,请将该命令的输出附加到您的问题中。
在旧版本的 bash 管道上,由于启用了日志记录功能(bash < 4.1),管道可能会中断。
type log
这应该返回类似“日志:未找到”的内容。如果它返回一个函数定义,请使用命令将其清除unset log。
trap -p
查看是否有任何陷阱输出链接到调试或日志记录。如果它们是和/或定义了日志函数,您需要找出它们的定义位置并(至少暂时)删除它们。
它们可以在 .bashrc、.bash_profile 和任何其他相关初始化文件中定义。由于它似乎也会影响 root,因此更有可能在/etc/bashrc 或 /etc/profile 等系统级文件中找到它。
至少您可以清除当前环境中的陷阱和日志功能,看看是否能解决问题。
检查这一点的另一种方法是使用(固定)运行管道命令
env -i ls | env -i grep a | env -i grep b | env -i grep c | env -i grep d
清除环境(对于该命令序列)。您可能需要更改命令以包含完整路径。看看ulimit -a在这种环境下的值是否有所不同也是值得的。
在运行管道 cmd 序列之前,在set -x命令行中键入,这将打开 bash 调试 - 所有“幕后”命令都将打印到屏幕上。您可能会看到一些奇怪的东西 - 调用另一个函数的钩子,类似于上面讨论的日志问题 - 或其他奇怪的东西。
使用 strace 运行命令:
strace ls | grep a | grep b | grep c | grep d
看看究竟发生了什么。如果您想发布这些结果,您可能需要将它们放在 Pastebin 或类似网站上并发布链接。这是解决该问题最有可能的方法,但输出可能难以解码。
查看您的日志后:
当使用 env -i 时,管道的每个阶段都需要使用它 - 每个阶段实际上都是一个单独的 shell 实例。我的错。
env -i ls | env -i grep a | env -i grep b | env -i grep c | env -i grep d
每次调用之间调用的日志记录函数与 DEBUG 陷阱相结合几乎肯定是我所指的错误。不幸的是,即使我订阅了 RHEL,也无法查看该错误。它是https://bugzilla.redhat.com/show_bug.cgi?id=720464
当日志记录与调试陷阱一起发生时,此错误导致了竞争条件,这正是您所发生的情况 - set -x 清楚地显示了发出的每个命令的相当广泛的日志记录(到系统日志)。
因为管道会创建子 shell,所以您不能只在顶级 shell 中清除它并发出管道命令。下一个管道阶段将定义它。对上面第 1 项中的更改进行重新测试将表明,即使没有这些钩子,它也能正常工作。
错误报告表明修复程序没有向后移植。我在这里放置了 rhel 的一些详细信息:http ://pastebin.com/dymenY7e
您需要清除陷阱和/或删除日志记录函数history_to_syslog 的定义。如果您具有root 访问权限,则绝对可以永久删除它。我在原来的答案中给出了一些关于去哪里寻找的提示。
您可以尝试检查 Centos 5 的 bash 更新,但我上面链接的信息表明没有创建到 rhel 5 的反向端口,因此不太可能是 Centos 5 的更新。
简要更新:
为了稍微澄清一下 bug 和故障模式之间的关系 - 发生的情况是,与日志记录函数和 DEBUG 挂钩关联的进程 id 进行交互的调用不按顺序发生 - 竞争条件 - 导致引用进程的调用,例如 getppid刚刚关闭,导致您看到错误。
顺便说一句,这是一种积极的日志记录功能。系统管理员显然不相信信任圈。
| 归档时间: |
|
| 查看次数: |
2071 次 |
| 最近记录: |