为什么从这个Python脚本到这个socat脚本的行缓冲管道无法工作?

时间:2016-03-05 05:43:54

标签: python shell unix buffer pipelining

我有一个Python脚本,可以将用户IRC命令(" / nick hello"," / quit"等)转换为IRC协议消息。它从stdin逐行输入并将转换后的消息输出到stdout。我还有一个非常简单的基于socat的脚本,只需打开一个给定地址和端口的TCP套接字。两者都可以自己搞定。但是当我尝试将IRC脚本的输出传递给套接字脚本时,没有任何反应。

这就是我想要发生的事情(为清楚起见,我添加&#34;&lt;&#34;输出和&#34;&gt;&#34;输入):< / p>

$ 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脚本在我将它传输到套接字脚本时不会进行行缓冲,我怎么能这样做呢?

1 个答案:

答案 0 :(得分:0)

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

#!/bin/python3 -u

现在有效!