为什么不能python执行通过stdin传递的zip存档? [英] why can't python execute a zip archive passed via stdin?

查看:203
本文介绍了为什么不能python执行通过stdin传递的zip存档?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个zip档案,包含 __ main __。py 档案:archive.zip

I have a zip archive containing a __main__.py file : archive.zip

python archive.zip
=> OK !

但不包含

cat archive.zip | python
=> File "<stdin>", line 1
SyntaxError: Non-ASCII character '\x9e' in file <stdin> on line 2,
but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

为什么在这两种模式之间有区别,是否有一种方法使管道工作,而不需要解压缩在python外?

why is there a difference between the 2 modes and is there a way to make the pipe work without unzipping outside of python ?

我通过网络接收这个归档,它一旦我收到它和尽可能快,所以我认为管道zip到python将工作!

I receive this archive over the network and want to execute it as soon as i receive it and as fast as possible so I thought that piping the zip into python would work !

推荐答案

原因是你可以'python file.zip',但不是'cat file.zip | python'是Python有'zipimport'内置的,所以当你对文件(或尝试导入)运行python时,zipimport在它们作为导入过程的一部分对它们进行破解。 (有关详细信息,请参阅导入模块)。

The reason that you can 'python file.zip', but not 'cat file.zip | python' is that Python has the 'zipimport' built in so that when you run python against files (or try to import them), zipimport takes a crack at them as part of the import process. (See the import module for details).

但是使用stdin,python不会尝试搜索流数据 - 因为流数据可以是任何东西 - 可以是由代码处理的用户输入是代码。没有办法知道,Python没有真正的努力,知道这个原因。

But with stdin, python does not make any attempt to search the streaming data - because the streaming data could be anything - could be user input that is handled by code, could be code. There's no way to know and Python makes no real effort to know for that reason.

编辑

偶尔,当你回答问题时,你认为我真的不应该告诉别人的答案,而不是因为你想要保密或拥有一些权力。只是因为他们走下去的路径不是正确的路径,你想帮助他们脱离他们正在挖掘的洞。这是其中一种情况。然而,对我的更好的判断,这里是一个非常hacky的方式完成类似于你想要的东西。这不是最好的方式,它可能是最糟糕的方式。

Occasionally, when you're answering questions - you think 'I really shouldn't tell someone the answer', not because you wish to be secretive or hold some amount of power over them. Simply because the path they're going down isn't the right path and you want to help them out of the hole they're digging. This is one of those situations. However, against my better judgement, here's an extremely hacky way of accomplishing something similar to what you want. It's not the best way, it's probably in fact the worst way to do it.

我刚刚和zipipporter玩了一段时间,尝试了所有的想法。我看着'imp','编译'以及..没有什么可以导入一个压缩模块(或egg)从内存到目前为止,我可以看到。因此,需要一个临时的步骤。

I just played around with the zipimporter for a while and tried all the tricks I could think of. I looked at 'imp', 'compile' as well.. Nothing can import a zipped module (or egg) from memory so far that I can see. So, an interim step is needed.

我会说这个,我很尴尬,甚至发布这个。不要向与您合作的人或您尊重的人显示此内容,因为他们笑这个可怕的解决方案。

I'll say this up front, I'm embarrassed to even be posting this. Don't show this to people you work with or people that you respect because they laugh at this terrible solution.

这是我做的:

mkdir foo
echo "print 'this is foo!'" >>foo/__init__.py
zip foo.zip -r foo
rm -rf foo                   # to ensure it doesn't get loaded from the filesystem
mv foo.zip somethingelse.zip # To ensure it doesn't get zipimported from the filesystem

然后,我运行这个程序使用

And then, I ran this program using

cat somethingelse.zip | python script.py

cat somethingelse.zip | python script.py

#!/usr/bin/python 

import sys
import os
import zipfile
import StringIO
import zipimport
import time

sys.path.append('/tmp')

class SinEater(object):
    def __init__(self):
        tmp = str(int(time.time()*100)) + '.zip'
        f = open(tmp, 'w')
        f.write(sys.stdin.read(1024*64)) # 64kb limit
        f.close()
        try:
            z = zipimport.zipimporter(tmp)
            z.load_module('foo')

        except:
            pass

if __name__ == '__main__':
    print 'herp derp'
    s = SinEater()

产生:

herp derp
this is new

一个解决方案将比这更好的一百万倍将有一个文件系统通知(inotify,kevent,无论什么窗口使用),监视一个目录的新的zip文件。当一个新的zip文件放在那个目录,你可以自动zipimport它。
但是,我不能强调足够即使该解决方案是可怕的。我不知道Ansible(什么真的),但我不能想象任何工程师认为这将是一个很好的解决方案,如何处理代码更新或远程控制。

A solution that would be about a million times better than this would be to have a filesystem notification (inotify, kevent, whatever windows uses) that watches a directory for new zip files. When a new zip file is dropped in that directory, you could automatically zipimport it. But, I cannot stress enough even that solution is terrible. I don't know much about Ansible (anything really), but I cannot imagine any engineer thinking that it would be a good solution for how to handle code updates or remote control.

这篇关于为什么不能python执行通过stdin传递的zip存档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆