ENV変数を保存するためにCircleCiボックスを使用しようとしています。私は通常そうします:
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
今一度実行するだけの拡張コマンドの場合、[...]この値を変数に保存してから、既に最終形式のエコーラインに追加する方法はありますか?
デフォルトでは、セクションを$ BASH_ENVとして印刷するのではなく、スクリプト自体var=$(command...)
でコマンド置換を実行してから結果を印刷します。だから:
var=$(some command)
echo "var='$var'" >> file
しかし、これはvar='value'
シェルの引用などを経ることになりますので、値に一重引用符が含まれれば壊れます。
代わりにprintf %q
、Bashでは、たとえば、次のように使用できます。
var=$(some command)
printf "var=%q\n" "$var" >> file
たとえば、値が$var
次の場合にit ain't so
生成されます。var=var=it\ ain\'t\ so
見苦しいですが、実行時に同じ値を生成します。