6

내에서 바이너리를 실행할 수 없습니다. 이것을 시도하고 나는 pyinstaller를 실행하여 희망대로 실행할 수있는 바이너리를 생성했다. 이 파일의 이름은 map_reader이며 람다 압축 패키지의 최상위에 있습니다. 다음은 내가 람다 함수 내에서이 도구를 실행하려고 파이썬 AWS의 람다 함수

내가 시도하고 도구를 실행하는 데 사용하고있는 코드입니다 :

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 

것을 말하는 :

  1. 가/tmp 디렉토리에 패키지에서 map_reader의 압축을 풉니 다. 그런 다음 /tmp/map_reader으로 참조하십시오. 하여 기사 Running Arbitrary Executables in AWS Lambda에 다음과 말했다 팀 와그너, AWS 람다의 일반 관리자에서 권장하는
  2. 그것을 수행 자신의 실행 파일을 포함

하는 것은 쉽다; 업로드 한 ZIP 파일에 파일을 패키지로 만든 다음 Node.js 또는 이전에 시작한 다른 프로세스에서 호출 할 때 생성 한 ZIP 파일 내의 상대 경로를 포함하여 참조하십시오. 당신의 기능 코드의 시작 부분에 다음은 포함 있는지 확인합니다 : 그것은 다음과 같은

import os os.environ['PATH']

처럼,

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

위의 코드는 노드 JS뿐만 파이썬에 대한 즉 명령 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로 옮겨야했습니다.

다른 문제는 우분투에서 pyinstaller를 실행하여 하나의 파일을 만드는 것이 었습니다. 나는 다른 곳에서 람다 컨테이너가 실행되는 것과 같은 아키텍쳐에서 컴파일하는 것에 대한 몇 가지 코멘트를 보았습니다. 따라서 Amazon Linux AMI를 기반으로 ec2에서 pyinstaller를 실행했습니다. 출력은 tmp로 이동하면 예상대로 작동하는 여러 .os 파일이었습니다.

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

/tmp에 바이너리를 이동하고 실행 나를

3

에 근무하고 나는이에 대해 조금 늦게 해요 알고 있지만 당신이이 일을 좀 더 일반적인 방법을 원하는 경우 (예를 들어 당신이있는 경우 바이너리를 많이하고 그들 모두를) 사용하지 않을 수도, 내가 할이 방법 당신이 당신의 평 파일 옆에 빈 폴더에있는 모든 바이너리를 넣어 제공하고 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)