【发布时间】:2010-12-11 19:50:28
【问题描述】:
这很奇怪,我不确定真正的罪魁祸首是谁。
我正在编写一些脚本,在 FreeBSD (6.2) 上?它广泛使用了以下***bash***ism:
do_something <(mysql --skip-column-names -B -e 'select ... from ... where ...;')
... 其中“do_something 是一个有点笨拙的实用程序(在 Perl 中),它不会从管道中读取。如果我使用常规文件它工作正常。我的 bash 脚本使用类似的东西exec 4< <(...) 与这些类型的查询(后面跟while read x y z <&4; do ... 形式的循环似乎从来没有任何问题。
但是,Perl (5.8.x) 似乎会定期阻塞(显然是永远)。我尝试用使用 sysread 的例程更改 chomp(my $data = <MYDATA>);,并在 Python 中编写了一些测试用例进行比较。这些似乎比惯用的 Perl 代码阻塞的频率要低得多,但有时它们仍然会这样做。 (使用f.read() 或os.read(f.fileno()...) 的Python 代码在这个问题上似乎表现得差不多)。
我尝试使用... <(cat ...)(我在其中查找常规文件)重现该问题,但似乎永远不会重现该停顿。
我看过一些 ktrace/kdump 数据...但我对 Linux strace 甚至 Solaris truss 熟悉得多> ...所以我还没有弄清楚那里发生了什么。
我想我们基本上可以排除 Perl,因为我已经使用 Python 重现了同样的问题......我看不出 bash 在这里做错了什么(它只是在创建/var/tmp/sh-np-xxx 中的命名管道并将进程连接到该管道)。
mysql shell/实用程序在做什么可能会导致这种情况?我认为我没有从其他任何东西(例如 cat 或 dd)中看到它。我还没有在 Linux 下测试过这种场景……但我在 Linux 下使用 <(...)(进程替换)已经很多年了,不记得曾经见过这种情况。
这是 FreeBSD 的问题吗?
当然,我可以使用临时文件来解决这个问题......但我肯定更愿意理解它为什么这样做(并避免临时文件带来的一些竞争和清理混乱)。
有什么建议吗?
【问题讨论】:
标签: mysql perl bash named-pipes freebsd