Perl select 函数无限期挂起

标签 perl freetds

对于这个非常基本的问题,我很抱歉,但我似乎没有找到问题的根本原因。

环境细节: Perl 5.14.1 通过 freeTDS tsql 连接到 MS SQL Server Linux x64

这是我的代码:

#!/usr/bin/perl -w
use IO::Select;
use strict;

my $query = "";
my $s = IO::Select->new();
$s->add(\*STDIN);
my @STD_IN = ();
if ($s->can_read(.5)) {
      @STD_IN = <STDIN>;
        }
$query .= "@STD_IN\n@ARGV";

my $myTmpFile = `mktemp /tmp/$ENV{USER}QueryXXXX`; chomp($myTmpFile);
`echo "use testDB\n$dbQuery\ngo\nquit" > $myTmpFile`;

print(`/usr/bin/tsql -H myhost -p 9999 -U myuser -P mypass -o q < $myTmpFile`);

当我运行这个脚本时,像这样

$>./myscript "select * from mytable"

它有时工作正常,但我经常看到脚本不确定地挂起。

我通过运行 ps -ef 进行了一些调试,它看起来是这样的:

kedar 24659 24574  0 05:50 ttyp3    00:00:00 /usr/bin/perl -w /home/kedar/myscript select * from mytable

这里挂起的原因是什么?我还不明白 - 这是一个非常简单的脚本。

我检查了 IO::Select 的 perl 文档,这就是它所说的 -

can_read    

$s->can_read([timeout])
Returns array of handles that are ready for reading. timeout is the maximum amount of time to wait before returning an empty list. If timeout is not given, and any handles are registered, then the call blocks.

但我的脚本中确实有超时。

有什么想法吗?请帮忙,因为我遇到了问题

PS:由于一些限制,一些变量、文件名和其他东西已经从原来的基础上进行了修改。 另外,这个脚本是以前别人写的,我需要先修复挂起。因此,如果您能想到替代和干净的方式来执行此操作,那就太好了!

最佳答案

@STD_IN = <STDIN>从文件句柄中读取 STDIN在列表上下文中,这意味着它会阻塞直到它收到 eof在文件句柄上。 IO::Select的功能,另一方面,只会告诉您所选文件句柄上是否有任何输入,而不是它是否包含所有输入。

所以在这种情况下你想阅读 STDIN在标量环境中 (*)。它可能看起来像这样:

if ($s->can_read(.5)) {
    push @STD_IN, scalar <STDIN>;
    # check if there is more than one line of input ready ...
    while ($s->can_read(0)) {
        push @STD_IN, scalar <STDIN>;
    }
}

(*) - 标量上下文在这里可能也不够。标量上下文将从文件句柄开始读取,直到下一个行尾字符或字符序列。对于缓冲输入或非结构化输入,IO::Select可能会告诉您输入可用,但该输入可能不包含换行符和 scalar <STDIN>调用会阻塞。在这种情况下,您可能不得不求助于一次加载输入一个字符(使用 getcread/sysread ),或者,如果您的操作系统支持,则设置一个非阻塞文件句柄。

关于Perl select 函数无限期挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32829418/

相关文章:

perl - 如何将参数传递给使用 eval 定义的 Perl 子例程?

windows - 使用 Perl 从 SID 获取帐户名

perl - 需要帮助解释这个 perl 代码

sql-server-2008 - 如何使用 freeTDS 和 unixODBC 配置 pyodbc 以正确接受来自 SQL Server 的字符串?

perl - DBI::Sybase 数据转换导致溢出

python - 多台主机上的并行 rsync

perl - 未观察到 FH 输出,同时观察到相同的 STDOUT 输出

azure-sql-database - 尝试从tsql连接到sql-azure时从服务器读取失败

FreeTDS 显示来自服务器的意外 EOF

centos - FreeTDS - 无法连接 : Adaptive Server is unavailable or does not exist