【问题标题】:Why isn't line-buffered piping from this Python script into this socat script working?为什么从这个 Python 脚本到这个 socat 脚本的行缓冲管道不起作用?
【发布时间】:2016-06-19 01:06:01
【问题描述】:

我有一个 Python 脚本,可以将用户 IRC 命令(“/nick hello”、“/quit”等)转换为 IRC 协议消息。它从标准输入逐行输入并将翻译后的消息输出到标准输出。我还有一个非常简单的基于 socat 的脚本,它只打开一个给定地址和端口的 TCP 套接字。两者都可以自己正常工作。但是当我尝试将 IRC 脚本的输出通过管道传输到套接字脚本时,什么也没有发生。

这是我想要发生的事情(为了清楚起见,我添加了“”作为输入):

$ user2irc | mksock 127.0.0.1 6667
< :irc.aardei-6600K.local NOTICE * :*** Looking up your hostname...
< :irc.aardei-6600K.local NOTICE * :*** Found your hostname (cached)
> /user aardbei
> /nick aardbei
< PING :1DE01324
> /pong 1DE01324
(...)

然而,实际上是这样的:

$ user2irc | mksock 127.0.0.1 6667
< :irc.aardei-6600K.local NOTICE * :*** Looking up your hostname...
< :irc.aardei-6600K.local NOTICE * :*** Found your hostname (cached)
> /user aardbei
> /nick aardbei
(nothing happens)

当我自己运行 IRC 脚本时会发生这种情况,显示它应该发送到套接字的内容:

$ user2irc
> /user aardbei
< USER aardbei 8 * :aardbei
> /nick aardbei
< NICK :aardbei

当我自己运行套接字脚本并手动输入由 IRC 脚本生成的相同 IRC 消息时会发生这种情况,表明 IRC 服务器确实响应了它们:

$ mksock 127.0.0.1 6667
< :irc.aardei-6600K.local NOTICE * :*** Looking up your hostname...
< :irc.aardei-6600K.local NOTICE * :*** Found your hostname
> USER aardbei 8 * :aardbei
> NICK aardbei
< PING :862B79F4
> PONG :862B79F4
(...)

我尝试通过 echo 将 IRC 消息传递到命令中,它工作得很好。可以看到服务器发回了一条 PING 消息:

$ echo -ne "USER aardbei 8 * :aardbei\r\nNICK :aardbei\r\n" | mksock 127.0.0.1 6667
:irc.aardei-6600K.local NOTICE * :*** Looking up your hostname...
:irc.aardei-6600K.local NOTICE * :*** Found your hostname (cached)
PING :FDB6F41D
ERROR :Closing Link: aardbei[127.0.0.1] (Read error)

我尝试将脚本的输出重定向到一个文件,然后将其读入套接字脚本,这也有效:

$ user2irc > prgdump
/user aardbei
/nick aardbei
^D

$ cat prgdump
USER aardbei 8 * :aardbei
NICK :aardbei

$ mksock 127.0.0.1 6667 < prgdump
:irc.aardei-6600K.local NOTICE * :*** Looking up your hostname...
:irc.aardei-6600K.local NOTICE * :*** Found your hostname (cached)
PING :CEFB97C0
ERROR :Closing Link: aardbei[127.0.0.1] (Read error)

$ cat prgdump | mksock 127.0.0.1 6667
:irc.aardei-6600K.local NOTICE * :*** Looking up your hostname...
:irc.aardei-6600K.local NOTICE * :*** Found your hostname (cached)
PING :A74E64E4
ERROR :Closing Link: aardbei[127.0.0.1] (Read error)

我在两个命令上都尝试了 stdbuf -oL:

$ stdbuf -oL user2irc | stdbuf -oL mksock 127.0.0.1 6667
:irc.aardei-6600K.local NOTICE * :*** Looking up your hostname...
:irc.aardei-6600K.local NOTICE * :*** Found your hostname
/user aardbei
/nick aardbei
(nothing happens)

我试着把它用管道输送到猫中:

$ user2irc | cat
/nick aardbei
(nothing happens)

我尝试通过显式行缓冲将其通过管道传输到 cat 中:

$ stdbuf -oL user2irc | stdbuf -oL cat
/nick aardbei
(nothing happens)

我尝试通过管道将 cat 插入套接字脚本:

$ cat | mksock 127.0.0.1 6667
< :irc.aardei-6600K.local NOTICE * :*** Looking up your hostname...
< :irc.aardei-6600K.local NOTICE * :*** Found your hostname (cached)
> USER aardbei 8 * :aardbei
> NICK aardbei
< PING :C2538D43

我尝试同时使用 bash 和 mksh。

这里是mksock的内容:

socat - TCP:$1:$2

这里是user2irc的内容:http://pastebin.com/jSDdHEEF

为什么当我将它通过管道传输到套接字脚本时,这个 Python 脚本不是行缓冲,我怎样才能做到这一点?

【问题讨论】:

    标签: python shell unix buffer pipelining


    【解决方案1】:

    好的,我通过在脚本第一行的 Python 命令中添加 -u(用于无缓冲)来修复它:

    #!/bin/python3 -u
    

    现在可以了!

    【讨论】:

      猜你喜欢
      • 2014-09-18
      • 2020-12-14
      • 2015-06-16
      • 2013-11-14
      • 2013-10-20
      • 2014-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多