这很奇怪,我不确定真正的罪魁祸首是谁。
我正在编写一些脚本,在 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) 似乎会定期阻塞(显然是永远阻塞)。我尝试chomp(my $data = <MYDATA>);
用一个使用sysread的例程来改变它,并用 Python 编写了一些测试用例进行比较。这些似乎比惯用的 Perl 代码阻塞的频率要低得多,但有时它们仍然会这样做。(使用f.read()
or的 Python 代码os.read(f.fileno()...)
似乎在这个问题上表现得差不多)。
我已经尝试使用... <(cat ...)
(我在cat常规文件的地方)重现该问题,但这似乎永远不会重现该停顿。
我浏览了一些ktrace/kdump数据……但我对 Linux strace甚至 Solaris truss更加熟悉……所以我还没有弄清楚那里发生了什么。
我想我们基本上可以排除 Perl,因为我已经使用 Python 重现了同样的问题......我看不出bash在这里做错了什么(它只是在/var/tmp/sh中创建了一个命名管道-np-xxx并将进程连接到那个)。
mysql shell/utility 正在做什么可能会导致这种情况?我认为我没有从其他任何东西(例如cat或dd)中看到它。我还没有在 Linux 下测试过这个场景……但我已经在 Linux 下使用<(...)
了(进程替换)多年,并且不记得曾经见过这个。
是 FreeBSD 的问题吗?
当然我可以使用临时文件解决这个问题......但我肯定更愿意理解它为什么这样做(并避免临时文件带来的一些竞争和清理混乱)。
有什么建议么?