我有一个Python脚本,可以将用户IRC命令("/nick hello","/quit"等)转换为IRC协议消息。 它从 stdin 中逐行输入,并将翻译后的消息输出到 stdout。 我还有一个非常简单的基于 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 * :aardbeirnNICK :aardbeirn" | 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 | 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 脚本不是行缓冲,我怎样才能让它这样做?
我通过将 -u(用于无缓冲)添加到脚本第一行的 Python 命令来修复它:
#!/bin/python3 -u
现在它工作了!