You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

$@变量正确插值问题:SSM脚本无法传递多参数

问题:SSM Runner脚本处理带参数的命令失败

我的EC2实例上有两个脚本:hello_world.sh(输出“hello world”)和echo.sh(接收并回显参数)。执行ssm_runner.sh dev hello_world.sh能正常运行,但执行ssm_runner.sh dev echo.sh hello时完全失效。原脚本代码如下:

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

解决方案

问题根源在于$@的插值逻辑:当传入多个参数(比如echo.sh hello)时,$@会被拆分成独立字段,直接拼进JSON会破坏格式,同时shell引号规则会让参数传递混乱。

以下是修复后的脚本,能正确处理带参数的命令:

#!/bin/bash
TARGET_ENV="$1"
shift

# 对所有后续参数转义,确保空格、特殊字符能正确传递
escaped_cmd=$(printf "%q " "$@")
# 构造完整的su执行命令
su_cmd="su -c './$escaped_cmd' - ec2-user"

commandid=$(aws ssm send-command \
    --document-name "AWS-RunShellScript" \
    --targets "Key=tag:Name,Values=$TARGET_ENV" \
    --parameters '{"commands":["'"$su_cmd"'"]}' \
    --query 'Command.CommandId' \
    --output text)

echo "$commandid"

关键修改点:

  1. 参数转义:用printf "%q " "$@"把每个参数转义成shell可正确解析的格式,哪怕参数包含空格、引号这类特殊字符也不会出错。
  2. 变量隔离:先把su的完整命令拼成一个变量,再插入到JSON中,避免直接拼接$@导致的字段拆分问题。
  3. JSON格式保证:通过'"$su_cmd"'的写法,把变量值正确嵌入JSON字符串,确保AWS能识别合法的JSON参数。

如果你的参数不会包含特殊字符,也可以用更简洁的写法:

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

不过第一种带转义的写法兼容性更强,适合各种复杂场景。

内容的提问来源于stack exchange,提问作者joyfuljoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:35:24