我试图在lambda函数中运行此工具:https://github.com/nicolas-f/7DTD-leaflet
该工具依赖于Pillow,它依赖于AWS lambda容器中不可用的映像库.为了试图绕过这个我运行pyinstaller来创建一个我希望可以执行的二进制文件.此文件已命名map_reader
并位于lambda zip包的顶层.
下面是我用来尝试运行该工具的代码:
command = 'chmod 755 map_reader' args = shlex.split(command) print subprocess.Popen(args) command = './map_reader -g "{}" -t "{}"'.format('/tmp/mapFiles', '/tmp/tiles') args = shlex.split(command) print subprocess.Popen(args)
这是第二次subprocess.Popen
调用时发生的错误:
[Errno 13] Permission denied: OSError
我怎样才能正确运行?
您可能被误导了问题的实质。
我认为第一个Popen不能成功运行。我认为它只是在标准错误中转储了一条消息,而您却没有看到它。可能是说
chmod: map_reader: No such file or directory
我建议您可以尝试以下两种方法之一:
从包中提取map_reader到/ tmp中。然后使用引用/tmp/map_reader
。
按照AWS Lambda总经理Tim Wagner的建议进行操作,他在“ 在AWS Lambda中运行任意可执行文件”一文中说:
包含自己的可执行文件很容易;只需将它们打包在您上载的ZIP文件中,然后在从Node.js或先前启动的其他进程中调用它们时就引用它们(包括您创建的ZIP文件中的相对路径)。确保在功能代码的开头包含以下内容:
process.env[‘PATH’] = process.env[‘PATH’] + ‘:’ + process.env[‘LAMBDA_TASK_ROOT’]
上面的代码适用于Node JS,但是适用于Python,就像下面的代码
import os
os.environ['PATH']
那应该使命令command = './map_reader
起作用。
如果它们仍然不起作用,您还可以考虑chmod 755 map_reader
在创建包并上传之前运行它(如在其他问题中所建议)。
我知道我为此事有些迟了,但是如果您想要一种更通用的方式(例如,如果您有很多二进制文件并且可能不会全部使用它们),这是我的方法,只要您将所有py文件旁边的bin文件夹中的二进制文件,以及lib文件夹中的所有库:
import shutil import time import os import subprocess LAMBDA_TASK_ROOT = os.environ.get('LAMBDA_TASK_ROOT', os.path.dirname(os.path.abspath(__file__))) CURR_BIN_DIR = os.path.join(LAMBDA_TASK_ROOT, 'bin') LIB_DIR = os.path.join(LAMBDA_TASK_ROOT, 'lib') ### In order to get permissions right, we have to copy them to /tmp BIN_DIR = '/tmp/bin' # This is necessary as we don't have permissions in /var/tasks/bin where the lambda function is running def _init_bin(executable_name): start = time.clock() if not os.path.exists(BIN_DIR): print("Creating bin folder") os.makedirs(BIN_DIR) print("Copying binaries for "+executable_name+" in /tmp/bin") currfile = os.path.join(CURR_BIN_DIR, executable_name) newfile = os.path.join(BIN_DIR, executable_name) shutil.copy2(currfile, newfile) print("Giving new binaries permissions for lambda") os.chmod(newfile, 0775) elapsed = (time.clock() - start) print(executable_name+" ready in "+str(elapsed)+'s.') # then if you're going to call a binary in a cmd, for instance pdftotext : _init_bin('pdftotext') cmdline = [os.path.join(BIN_DIR, 'pdftotext'), '-nopgbrk', '/tmp/test.pdf'] subprocess.check_call(cmdline, shell=False, stderr=subprocess.STDOUT)