我有一个小型服务器程序,它接受TCP或本地UNIX套接字上的连接,读取一个简单的命令,并根据命令发送一个回复.问题是客户端有时可能对答案没兴趣并且提前退出,因此写入该套接字将导致SIGPIPE并使我的服务器崩溃.什么是防止崩溃的最佳做法?有没有办法检查线的另一边是否还在读?(select()似乎在这里不起作用,因为它总是说套接字是可写的).或者我应该用处理程序捕获SIGPIPE并忽略它?
我有一个Python3脚本将其输出写入stdout,但是当我将输出传输到head或tail时,它会抱怨.请注意下面的示例输出中它的工作方式,即head返回前两行输出.
> ./script.py '../Testdata/*indels.ss' -m 5 | head -2 ~/Databases/Avian_genomes/Sandbox/combined
xread
2999 50
Traceback (most recent call last):
File "./new.py", line 194, in <module>
sys.stdout.write(lineout)
IOError: [Errno 32] Broken pipe
Exception IOError: IOError(32, 'Broken pipe') in <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> ignored
Run Code Online (Sandbox Code Playgroud)
相比之下,脚本没有问题,其输出通过管道传输到awk,如下所示.
> ./script.py '../Testdata/*indels.ss' -m 5 | awk 'NR < 3 {print $0}' ~/Databases/Avian_genomes/Sandbox/combined
xread
2999 50
Run Code Online (Sandbox Code Playgroud)
如果您需要脚本中的某些代码超出错误消息中包含的内容,请告诉我.我不确定什么是相关的.
我正在尝试打印在我的格式化的元组列表stdout.为此,我使用str.format方法.一切正常,但是当我输出输出以使用head命令a 查看第一行时IOError.
这是我的代码:
# creating the data
data = []$
for i in range(0, 1000):
pid = 'pid%d' % i
uid = 'uid%d' % i
pname = 'pname%d' % i
data.append( (pid, uid, pname) )
# find max leghed string for each field
pids, uids, pnames = zip(*data)
max_pid = len("%s" % max( pids) )
max_uid = len("%s" % max( uids) )
max_pname = len("%s" % max( pnames) )
# my template …Run Code Online (Sandbox Code Playgroud) 我尝试编写一些代码来捕获Broken Pipe Error.代码应该在Python 2.x和Python 3.x中运行.
在Python 2.xa中,断管用a表示 socket.error
socket.error: [Errno 32] Broken pipe
Run Code Online (Sandbox Code Playgroud)
这在Python 3.x中已经改变了 - 现在破损的管道就是了 BrokenPipeError
BrokenPipeError: [Errno 32] Broken pipe
Run Code Online (Sandbox Code Playgroud)
异常处理的语法也有所改变(参见/sf/answers/2412417871/),所以我需要做的是:
try:
do_something()
except BrokenPipeError as e: # implies Python 3.x
resolve_for_python2()
except socket.error as e:
if sys.version_info[0] == 2: # this is necessary, as in Python >=3.3
# socket.error is an alias of OSError
# https://docs.python.org/3/library/socket.html#socket.error
resolve_for_python3()
else:
raise
Run Code Online (Sandbox Code Playgroud)
还有(至少)剩下的一个问题:在Python 2.x中没有BrokenPipeError,所以每当Python 2.x中出现异常时do_something()都会抛出另一个异常并抱怨它不知道BrokenPipeError.正如socket.error在Python 3.xa中弃用的那样,在不久的将来,Python 3.x中可能出现类似的问题.
我该怎么做才能使这些代码在Python 2.x和Python …
当将 Python 脚本的输出传递到带有无效参数的管道时,我遇到了一些(对我来说)奇怪的行为wc。
\xce\xbb python test.py\nHello!\n\xce\xbb python test.py | wc -li\nwc: unknown option -- i\nTry 'wc --help' for more information.\nException ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='cp1252'>\nOSError: [Errno 22] Invalid argument\nRun Code Online (Sandbox Code Playgroud)\n\n这里发生了什么?
\n\n我的配置是
\n\n我有一个命令,我将运行生成随机字符串:
var=`< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c8`
Run Code Online (Sandbox Code Playgroud)
当我在交互式bash会话中运行此命令时,我绝对没有错误.但是,当我将此命令放入脚本并将其作为脚本运行时,我得到了由tr指示的Broken pipe错误.我已经阅读了几个相关的主题,但仍然没有答案为什么脚本和交互行为是不同的,有没有办法用shell选项或其他东西来控制它?
编辑I:
关于给出的评论,我发现可以通过以下方式控制指示损坏的管道错误:
trap - SIGPIPE # to ignore errors
Run Code Online (Sandbox Code Playgroud)
和
trap "" SIGPIPE # to display errors
Run Code Online (Sandbox Code Playgroud)
编辑二:
好吧,我提供了有关复制条件的错误信息.最后,似乎python包装器使用os.system()调用脚本引起的问题:
python -c "import os; os.system('sh -c \"< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c8\"')"
Run Code Online (Sandbox Code Playgroud)
给定的行产生与使用的OS无关的管道错误.
编辑III:
这个主题在这里讨论过:https: //mail.python.org/pipermail/python-dev/2005-September/056341.html