Search code examples
linuxbashsh

Proper variable interpolation for $@


#!/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

Solution

  • #!/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"