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()
的 shell 命令。因此,我们必须确保通过执行以下操作来处理它:
exiftool.open({ shell: true })
此时您可能已完成,或者可能会遇到以下错误:
perl:加载共享库时出错:libcrypt.so.1:无法打开共享对象文件:没有这样的文件或目录
。我不确定如何最好地解决这个问题。也许自己编译 Perl 并自己创建一个层可以防止这种情况发生。但对我有用的快速而肮脏的解决方案是从本地 ubuntu 系统复制 libcrypt.so.1
文件 ($ whereis libcrypt.so.1
),将其放入放入名为 lib
的文件夹中,压缩该文件夹并将其作为新层上传。
关于node.js - NodeJs : Exiftool can not be spawned in AWS Lambda environment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58932115/