node.js - NodeJs:无法在 AWS Lambda 环境中生成 Exiftool
问题描述
Exiftool 无法在 aws lambda 环境中生成,出现以下错误:
ERROR { Error: spawn /var/task/node_modules/dist-exiftool/node_modules/exiftool.pl/vendor/exiftool ENOENT
at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
at onErrorNT (internal/child_process.js:415:16)
at process._tickCallback (internal/process/next_tick.js:63:19)
errno: 'ENOENT',
code: 'ENOENT',
syscall:
'spawn /var/task/node_modules/dist-exiftool/node_modules/exiftool.pl/vendor/exiftool',
path:
'/var/task/node_modules/dist-exiftool/node_modules/exiftool.pl/vendor/exiftool',
spawnargs:
[ '-echo2', '1574158488325', '-stay_open', 'True', '-@', '-' ] }
一个函数在 AWS Lamda 上与 NodeJs 8.10 版一起正常工作,但我想将此函数升级到 NodeJs 10.X 版。我未能在 NodeJs 10.X 上运行函数。我总是在以下行出现错误。
const ep = new exiftool.ExiftoolProcess(exiftoolBin);
我的功能:
const exiftool = require('node-exiftool')
const exiftoolBin = require('dist-exiftool')
const fs = require('fs')
const path = require('path')
const ep = new exiftool.ExiftoolProcess(exiftoolBin)
const PHOTO_PATH = path.join(__dirname, 'photo.jpg')
const rs = fs.createReadStream(PHOTO_PATH)
ep.open()
.then(() => ep.readMetadata(rs, ['-File:all']))
.then((res) => {
console.log(res)
})
.then(() => ep.close(), () => ep.close())
.catch(console.error)
请帮我解决这个问题。
谢谢你。
解决方案
错误消息相当具有误导性,但有一些提示。路径说/exiftool.pl/
pl 通常是 perl。如果您打开 exiftool 文件,您将#!/usr/bin/perl -w
在第一行看到。
实际缺少的(ENOENT)是一个 perl 二进制文件
AWS 显然从运行时环境中删除了各种二进制文件。现在看来最好的做法是使用层来添加缺失的依赖项。
因此,首先,将 perl 作为层添加到您的 AWS Lambda 函数中,为此您可以使用来自https://metacpan.org/pod/AWS::Lambda的 ARN 。然后 perl 二进制文件应该可以在/opt/bin/perl
,它与 #! 不匹配。的脚本,所以我们要调整功能代码:
const { ExiftoolProcess } = require('node-exiftool');
const exiftoolBin = require('dist-exiftool');
// Get perl binary path from environment variables or fallback to default.
const perlBin = process.env.PERL_BIN || '/opt/bin/perl';
// Instead of calling the perl script directly causing #! to choose the
// interpreter path, we'll pass the script path to the interpreter directly.
const exiftool = new ExiftoolProcess(`${perlBin} ${exiftoolBin}`);
但是现在传递给的路径ExiftoolProcess
不再是有效的文件路径。这是一个传递给child_process.spawn()
. 因此,我们必须确保通过以下方式处理它:
exiftool.open({ shell: true })
此时您可能已完成,或者您可能会遇到以下错误:
perl: error while loading shared libraries: libcrypt.so.1: cannot open shared object file: No such file or directory
. 我不确定如何最好地解决这个问题。也许自己编译 perl 并自己创建一个层可以防止它。但是对我有用的快速而肮脏的解决方案是libcrypt.so.1
从我的本地 ubuntu 系统 ( $ whereis libcrypt.so.1
) 复制文件,将其放入名为 的文件夹lib
中,压缩该文件夹并将其作为新层上传。
推荐阅读
- ios - iOS Vision 框架人脸跟踪的高 CPU 和能源使用
- reactjs - 赛普拉斯 while 循环
- mysql - 在 mySQL 工作台 MAC 中,secure_file_priv=NULL
- asp.net-core - 如何摆脱警告“从应用程序代码调用'BuildServiceProvider'......”
- swift - 作为参数传递的 ViewController 未被取消初始化(Swift)
- python - 如何在 Python 中做这个特定的列表理解?
- asp.net - 带有 PagedList 问题的 ASP.NET Core 中的下拉 PageSize 选择
- c# - 获取实体框架中按不同属性分组的最新项目列表
- python - 如何在 Python 列表初始化中放置条件
- json - 确保字符串为 JSON 格式的方法