Home > front end >  Proper variable interpolation for $@
Proper variable interpolation for $@

Time:02-03

#!/bin/bash
TARGET_ENV="$1"
shift
commandid=$(aws ssm send-command \
    --document-name "AWS-RunShellScript" \
    --targets Key=tag:Name,Values=$TARGET_ENV \
    --parameters '{"commands":["su -c \"./'$@'\" - ec2-user"]}' \
    --query 'Command.CommandId' \
    --output text)

echo $commandid

(ssm_runner.sh)

My ec2 instance have a script called hello_world.sh that prints hello world and echo.sh which accepts parameters and echo it.

The following works

ssm_runner.sh dev hello_world.sh

but this one doesn't

ssm_runner.sh dev echo.sh hello

CodePudding user response:

#!/bin/bash

TARGET_ENV="$1"
shift

# Compose a complete su command which can be safely interpreted with
# `eval` or `bash -c`.
printf -v cmd '%q ' "$@"
su="su -c ./${cmd% } - ec2-user"

# Create JSON using jq.
params=$(jq -c --arg su "$su" '.commands = [$su]' <<< '{}')

# Execute.
commandid=$(aws ssm send-command \
    --document-name "AWS-RunShellScript" \
    --targets Key=tag:Name,Values="$TARGET_ENV" \
    --parameters "$params" \
    --query 'Command.CommandId' \
    --output text)

echo "$commandid"

CodePudding user response:

You could do the following.

  1. At the ssm_runner.sh script change the single quotation for positional parameters variable $@, to double quotation. And make it start from second argument, which corresponds to the script you will pass by terminal call.
    --parameters '{"commands":["su -c \"./'$@'\" - ec2-user"]}' \
    --parameters '{"commands":["su -c \"./"${@:2}"\" - ec2-user"]}' \

Notice that ${@:2} stands for positional parameters variable to start from second argument.

  1. The next thing it's to call the script this way:
    ssm_runner.sh dev "echo.sh hello"
                  --- ---------------
                   |         |
                  1st        --> 2nd pos. arg. as a single one thanks to quotation.
                pos. arg.
              we will ignore.

Basically, you needed your echo.sh to be the first thing your su -c <...> found out to execute, i.e., trim off dev and keep the rest as an argument, playing around with positional parameters.

  • Related