回显命令

回显命令

我正在尝试使用 CircleCi 框存储 ENV 变量。我通常这样做:

echo 'export FILE=$(ls bin | head -n 1)' >> $BASH_ENV

这非常适合简单的命令,并且会在 $BASH_ENV 中生成输出

export FILE=$(ls bin | head -n 1)

现在,对于我只需要运行一次的扩展命令,这很复杂并且不起作用。

echo 'export INSTANCE_ID=$(aws ec2 run-instances --instance-type t3.large\
--image-id $AMI --key-name circleci-key --count 1 --security-group-ids $SG\
--subnet-id $SUBNET --network-interfaces "{\"AssociatePublicIpAddress\": true, \"DeviceIndex\": 0, \"SubnetId\": \"$SUBNET\", \"Groups\": [\"$SG\"]}"\
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=instance-from-circleci}]'\
 | jq '.Instances[0].InstanceId' --raw-output)' >> $BASH_ENV

这段代码一旦添加到 $BASH_ENV 就会在每次运行时执行source $BASH_ENV

有没有一种方法可以简单地将这个值存储到一个变量中,然后将其添加到已经处于最终形式的回显行中?

就像是:

echo 'export $INSTANCE_ID' >> $BASH_ENV

答案1

为了避免转义引号带来的麻烦,使用此处文档更容易:

cat << 'EOF' >> "$BASH_ENV"
export INSTANCE_ID="$(
  aws ec2 run-instances \
    --instance-type t3.large \
    --image-id "$AMI" \
    --key-name circleci-key \
    --count 1 \
    --security-group-ids "$SG" \
    --subnet-id "$SUBNET" \
    --network-interfaces '
      {
        "AssociatePublicIpAddress": true,
        "DeviceIndex": 0,
        "SubnetId": "'"$SUBNET"'",
        "Groups": ["'"$SG"'"]
      }' \
    --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=instance-from-circleci}]' |
  jq '.Instances[0].InstanceId' --raw-output)"
EOF

(还解决了缺少引号的问题,并提高了可读性)。

EOF请注意( )周围的引号'EOF'很重要。如果没有它们,此处文档中的变量和命令替换将被扩展,并且\在生成此处文档时尾部将被视为行延续。

答案2

现在,对于我只需要运行一次的扩展命令,[...]有没有一种方法可以简单地将这个值存储到一个变量中,然后将其添加到已经处于最终形式的回显行中?

好吧,基本上,不是将var=$(command...)部分打印到 $BASH_ENV,而是在脚本本身中运行命令替换,然后打印结果。所以:

var=$(some command)
echo "var='$var'" >> file

但请注意,将var='value'经过 shell 的引号处理等,因此如果该值可以包含单引号,则会中断。

相反,您可以printf %q在 Bash 中使用例如:

var=$(some command)
printf "var=%q\n" "$var" >> file

如果 中的值为$var例如it ain't so,则会产生var=var=it\ ain\'t\ so。丑陋,但执行时产生相同的值。

相关内容