S3中有一个hello.js,其中包含
function greet() {
console.log(" From Greetings: ");
}
尝试加载此文件并执行脚本的nodeJS lambda。 访问 s3 的权限有效,脚本能够加载。但当它调用 exec 时会发生什么还不清楚。没有错误,但日志中也没有打印“From Greetings”。
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const { exec } = require('child_process');
exports.handler = async (event, context) => {
const s3Bucket = 'monitor-state';
const s3Key = 'hello.js';
const params = { Bucket: s3Bucket, Key: s3Key };
try {
const data = await s3.getObject(params).promise();
const script = data.Body.toString();
// Execute the script
exec(`node -e "${script}"`, (error, stdout, stderr) => {
if (error) {
console.error(`Script execution error: ${error}`);
return context.fail('Error executing the script.');
} else {
console.log('Script execution output:');
console.log(stdout);
return context.succeed('Script executed successfully.');
}
});
} catch (error) {
console.error('Error fetching the script from S3:', error);
return context.fail('Error executing the script.');
}
};
我尝试了几种调用 exec 的方法,但似乎都不起作用。
您的 lambda 处理程序运行
exec
但不会等待子进程完成。
exec
立即返回,并且由于您的处理程序是异步的,因此处理程序会在其之后立即返回一个已完成的承诺。这足以让 Lambda 停止处理。
将你的 exec 回调变成一个承诺并等待它:
const AWS = require("aws-sdk");
const s3 = new AWS.S3();
const { exec } = require("child_process");
exports.handler = async () => {
const s3Bucket = "monitor-state";
const s3Key = "hello.js";
const params = { Bucket: s3Bucket, Key: s3Key };
const data = await s3.getObject(params).promise();
const script = data.Body.toString();
// Execute the script
const [stdout, stderr] = await new Promise((resolve, reject) =>
exec(`node -e "${script}"`, (error, stdout, stderr) => {
if (error) {
reject(error);
}
resolve([stdout, stderr]);
}),
);
console.log('Script execution output:');
console.log(stdout);
};
如果您使用 Promise,则无需使用
context
,所有被拒绝的 Promise 将被视为错误并记录到 CloudWatch。
此外,在每次 Lambda 调用时从 S3 加载代码的用例是什么?根据您的任务,最好将其放在 Lambda 层或使用 Step 函数。