可以在AWS Lambda函数中编写bash脚本

时间:2016-01-06 09:27:23

标签: bash amazon-web-services aws-lambda

我可以在Lambda函数中编写一个bash脚本吗?我在aws文档中读到它可以执行用Python,NodeJS和Java 8编写的代码。

在一些文件中提到可以使用Bash,但没有具体的证据支持它或任何例子

8 个答案:

答案 0 :(得分:15)

可能有帮助的东西,我正在使用Node来调用bash脚本。我使用以下代码作为处理程序将脚本和nodejs文件以zip格式上传到lambda。

exports.myHandler = function(event, context, callback) {
  const execFile = require('child_process').execFile;
  execFile('./test.sh', (error, stdout, stderr) => {
    if (error) {
      callback(error);
    }
    callback(null, stdout);
  });
}

您可以使用回调来返回所需的数据。

答案 1 :(得分:11)

正如您所提到的,AWS没有提供使用Bash编写Lambda函数的方法。

要解决它,如果你真的需要bash功能,你可以"包装"你的任何语言的bash脚本。

这是Java的一个例子:

Process proc = Runtime.getRuntime().exec("./your_script.sh");  

根据您的业务需求,您应该考虑使用本机语言(Python,NodeJS,Java)来避免性能损失。

答案 2 :(得分:7)

我能够使用Amazon Lambda - Python捕获shell命令uname输出。

以下是代码库。

from __future__ import print_function

import json
import commands

print('Loading function')

def lambda_handler(event, context):
    print(commands.getstatusoutput('uname -a'))

显示输出

START RequestId: 2eb685d3-b74d-11e5-b32f-e9369236c8c6 Version: $LATEST
(0, 'Linux ip-10-0-73-222 3.14.48-33.39.amzn1.x86_64 #1 SMP Tue Jul 14 23:43:07 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux')
END RequestId: 2eb685d3-b45d-98e5-b32f-e9369236c8c6
REPORT RequestId: 2eb685d3-b74d-11e5-b31f-e9369236c8c6  Duration: 298.59 ms Billed Duration: 300 ms     Memory Size: 128 MB Max Memory Used: 9 MB   

有关详细信息,请查看链接 - https://aws.amazon.com/blogs/compute/running-executables-in-aws-lambda/

答案 3 :(得分:6)

AWS最近宣布了“ Lambda运行时API和Lambda层”,这两项新功能使开发人员能够build custom runtimes。因此,现在可以在Lambda中直接运行甚至bash脚本,而不会受到黑客攻击。

由于这是一项非常新的功能(2018年11月),因此尚无足够的资料,仍然需要完成一些手动工作,但是您可以参考this Github repo作为示例与(免责声明:我没有测试)。在bash中的示例处理程序下方:

function handler () {
  EVENT_DATA=$1
  echo "$EVENT_DATA" 1>&2;
  RESPONSE="{\"statusCode\": 200, \"body\": \"Hello World\"}"
  echo $RESPONSE
}

这实际上打开了在Lambda中运行任何编程语言的可能性。这是有关发布自定义Lambda运行时的AWS tutorial

答案 4 :(得分:2)

可以使用' child_process'节点模块。

const exec = require('child_process').exec;

exec('echo $PWD && ls', (error, stdout, stderr) => {
  if (error) {
    console.log("Error occurs");
    console.error(error);
    return;
  }
  console.log(stdout);
  console.log(stderr);
});

这将显示当前工作目录并列出文件。

答案 5 :(得分:1)

AWS现在基于此announcement here支持自定义运行时。我已经测试过bash脚本,并且可以正常工作。您所需要做的就是创建一个新的lambda并选择类型为runtime的{​​{1}},它将创建以下文件结构:

Custom

示例mylambda_func |- bootstrap |- function.sh

Bootstrap

示例#!/bin/sh set -euo pipefail # Handler format: <script_name>.<function_name> # The script file <script_name>.sh must be located in # the same directory as the bootstrap executable. source $(dirname "$0")/"$(echo $_HANDLER | cut -d. -f1).sh" while true do # Request the next event from the Lambda Runtime HEADERS="$(mktemp)" EVENT_DATA=$(curl -v -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next") INVOCATION_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2) # Execute the handler function from the script RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA") # Send the response to Lambda Runtime curl -v -sS -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$INVOCATION_ID/response" -d "$RESPONSE" done

handler.sh

P.S。但是,在某些情况下,由于环境限制,您无法实现所需的条件,在这种情况下,需要AWS Systems Manager根据您更熟悉的知识{或定期使用{{ 1}}。

有关bash以及如何压缩和发布它的更多信息,请检查以下链接:

答案 6 :(得分:0)

现在,您可以通过提供自定义运行时来创建以任何一种语言编写的Lambda函数,该运行时可以教Lambda函数了解您要使用的语言的语法。

您可以按照此了解更多AWS Lambda runtimes

答案 7 :(得分:0)

正如其他人指出的那样,在 Node.js 中您可以使用 child_process 模块,它是 Node.js 内置的。这是一个完整的工作示例:

app.js

'use strict'
const childproc = require('child_process')

module.exports.handler = (event, context) => {
    return new Promise ((resolve, reject) => {
        const commandStr = "./script.sh"
        const options = {
            maxBuffer: 10000000,
            env: process.env
        }
        childproc.exec(commandStr, options, (err, stdout, stderr) => {
            if (err) {
                console.log("ERROR:", err)
                return reject(err)
            }
            console.log("output:\n", stdout)
            const response = {
                statusCode: 200,
                body: {
                    output: stdout
                }
            }
            resolve(response)
        })
    })
}

script.sh

#!/bin/bash

echo $PWD
ls -l

response.body.output

/var/task
total 16
-rw-r--r-- 1 root root 751 Oct 26  1985 app.js
-rwxr-xr-x 1 root root  29 Oct 26  1985 script.sh

(注意:我在实际的 Lambda 容器中运行它,它确实将年份显示为 1985)。

显然,您可以将任何您想要的 shell 命令放入 script.sh,只要它包含在 Lambda 预构建容器中即可。如果您需要预构建容器中没有的命令,您还可以构建自己的自定义 Lambda 容器。