首页 > 解决方案 > Bash:进程块 b/c 读取循环有时无法从文件描述符中读取更多数据,但手动 cat /proc//fd/能够

问题描述

设置:

我有一个复杂的脚本,它启动一个 postgres 并将输出重定向到文件描述符 3

exec 3< <(su -l postgres -c "/usr/local/pgsql/bin/postmaster -p '$port' -d 3 -D '$dataDir' 2>&1 & echo \$!")

然后在它之后,我读取 postgres 写入该文件描述符的数据

while [ true ]
do
  read -u 3 line

  //Do something or break

  fi
done

问题:

大多数情况下,这只是工作。但有时一切都会卡住,直到我cat /proc/<pid>/fd/3在命令行上手动执行,这解决了问题并使脚本继续。

到目前为止我的分析:

我对发生的情况的假设是,无论出于何种原因,都会read停止清空 fd(3) 的缓冲区,而是总是将相同的内容放入$line然后 postgres 停止,因为它在尝试写入 fd(3) 时被阻止导致僵局。

这总是在 postgres 关闭时同时记录大量调试信息时发生。

当我这样做时cat /proc/<pid>/fd/3,缓冲区似乎被清空了,postgres 继续并关闭,我正在读取日志并检查 postgres 是否退出的脚本继续。

我试图增加文件描述符缓冲区,但不知道如何。

sysctl -w net.unix.max_dgram_qlen=20480

没有解决这个问题。

问题:

1:为什么手动 cat 工作时读取失败?
2:如何增加文件描述符的缓冲区?

附加信息:

美分操作系统 7:3.10.0-1160.15.2.el7.x86_64

如果多个这样的脚本并行运行(针对不同的 postgres 数据目录),这种情况似乎更频繁地发生

它在服务器更新较大后开始发生,但可能是巧合,因为当时我们还增加了并行脚本的数量

标签: bashcentoscentos7

解决方案


推荐阅读