问题
Can I write a bash script inside a Lambda function? I read in the aws docs that it can execute code written in Python, NodeJS and Java 8.
It is mentioned in some documents that it might be possible to use Bash but there is no concrete evidence supporting it or any example
回答1:
Something that might help, I'm using Node to call the bash script. I uploaded the script and the nodejs file in a zip to lambda, using the following code as the handler.
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);
});
}
You can use the callback to return the data you need.
回答2:
As you mentioned, AWS does not provide a way to write Lambda function using Bash.
To work around it, if you really need bash function, you can "wrap" your bash script within any languages.
Here is an example with Java:
Process proc = Runtime.getRuntime().exec("./your_script.sh");
Depending on your business needs, you should consider using native languages(Python, NodeJS, Java) to avoid performance loss.
回答3:
AWS recently announced the "Lambda Runtime API and Lambda Layers", two new features that enable developers to build custom runtimes. So, it's now possibile to directly run even bash scripts in Lambda without hacks.
As this is a very new feature (November 2018), there isn't much material yet around and some manual work still needs to be done, but you can have a look at this Github repo for an example to start with (disclaimer: I didn't test it). Below a sample handler in bash:
function handler () {
EVENT_DATA=$1
echo "$EVENT_DATA" 1>&2;
RESPONSE="{\"statusCode\": 200, \"body\": \"Hello World\"}"
echo $RESPONSE
}
This actually opens up the possibility to run any programming language within a Lambda. Here it is an AWS tutorial about publishing custom Lambda runtimes.
回答4:
I just was able to capture a shell command uname
output using Amazon Lambda - Python.
Below is the code base.
from __future__ import print_function
import json
import commands
print('Loading function')
def lambda_handler(event, context):
print(commands.getstatusoutput('uname -a'))
It displayed the output
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
For More information check the link - https://aws.amazon.com/blogs/compute/running-executables-in-aws-lambda/
回答5:
Its possible using the 'child_process' node module.
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);
});
This will display the current working directory and list the files.
回答6:
AWS supports custom runtimes now based on this announcement here. I already tested bash script and it worked. All you need is to create a new lambda and choose runtime
of type Custom
it will create the following file structure:
mylambda_func
|- bootstrap
|- function.sh
Example 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
Example handler.sh
:
function handler () {
EVENT_DATA=$1
RESPONSE="{\"statusCode\": 200, \"body\": \"Hello from Lambda!\"}"
echo $RESPONSE
}
P.S. However in some cases you can't achieve what's needed because of the environment restrictions, such cases need AWS Systems Manager to Run command
, OpsWork (Chef/Puppet) based on what you're more familiar with or periodically using ScheduledTasks
in ECS cluster.
More Information about bash and how to zip and publish it, please check the following links:
- https://docs.aws.amazon.com/en_us/lambda/latest/dg/runtimes-walkthrough.html
- https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html
来源:https://stackoverflow.com/questions/34629574/can-bash-script-be-written-inside-a-aws-lambda-function