6

中运行二进制我想运行一个lambda函数中这个工具:https://github.com/nicolas-f/7DTD-leaflet无法从蟒蛇AWS lambda函数

的工具依赖于枕头取决于在AWS拉姆达容器不可用影像库。为了解决这个问题,我运行了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电话:

<subprocess.Popen object at 0x7f08fa100d10> 
[Errno 13] Permission denied: OSError 

如何运行这是否正确?

+0

我猜你正在运行的环境确实如此不允许您将本地文件设置为可执行文件。 “权限被拒绝”可能正是它所说的。 – Blckknght

回答

3

您可能被误解为问题实际存在。

我不认为第一个Popen成功运行。我认为它只是在标准错误中抛出了一条消息,而你没有看到它。它可能说

chmod: map_reader: No such file or directory 

我建议你可以尝试这两种2:

  1. 从包装到/ tmp中提取map_reader。然后参考/tmp/map_reader
  2. 做它的建议蒂姆·瓦格纳,AWS LAMBDA总经理谁的文章说Running Arbitrary Executables in AWS Lambda如下所示:

包括你自己的可执行文件是容易的;只需将它们打包到您上传的ZIP文件中,然后在您从Node.js或您之前启动的其他进程调用它们时引用它们(包括您创建的ZIP文件中的相对路径)。确保您包括在你的函数代码开始执行以下操作:

process.env[‘PATH’] = process.env[‘PATH’] + ‘:’ + process.env[‘LAMBDA_TASK_ROOT’] 

上面的代码是节点JS但对于Python的,它像下面

import os os.environ['PATH']

那应该使命令command = './map_reader <arguments>工作。

如果他们仍然无法工作,您也可以考虑在之前运行chmod 755 map_reader创建包并上传它(如建议in this other question)。

+0

标记为正确,但它不是我的完整解决方案。我会在另一个问题上发表另一个答案。这里至关重要的是将二进制文件移动到/ tmp,以便我可以采取行动。 – stevepkr84

+0

我忘了提及确保你已经编译好了Amazon Linux。我以为你照顾了。我很高兴你明白了。 –

+0

没有添加LAMBDA_TASK_ROOT到你的路径不适合你? –

2

这里有两个问题。首先,根据Jeshan的回答,我必须先将二进制文件移动到/ tmp,然后才能正确访问它。

另一个问题是我在Ubuntu上运行pyinstaller,创建一个文件。我在别处看到了一些有关确保在lambda容器运行的相同体系结构上编译的评论。因此,我在基于Amazon Linux AMI的ec2上运行pyinstaller。输出是多个.os文件,当移动到tmp时,按预期工作。

1
copyfile('/var/task/yourbinary', '/tmp/yourbinary') 
os.chmod('/tmp/yourbinary', 0555) 

移动二进制/tmp并使其可执行的工作对我来说

3

我知道我有点晚了这一点,但如果你想这样做的更通用的方法(例如,如果你有大量的二进制文件,可能不会使用它们),我该怎么办呢,只要你把你所有的二进制文件的bin文件夹旁边的PY文件,并在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)