本題
作成したスクリプトで値を取得したら、「*」が「\052」となっていて困った話です。
原因
*が\052のように表示される理由は、文字のエスケープシーケンスによるものです。
アスタリスク(*)は、ASCII文字コードで10進数の42番に割り当てられおり、これを8進数で表すと「052」になります。
そのため特段*として表示する処理を入れていないと、\052として出力されます。
API等では、*等の特殊文字をセキュリティの関係上エスケープして返却します。
遭遇したシーン
Route53の情報を一括でawsCLIで取得した時に発生
例
・期待した出力サンプル
"*.example.com"
・実際の出力サンプル
"\052.example.com"
実際のコード
#!/bin/bash
# エラー発生時に即座に終了
set -e
# 基本設定
DATE=$(date +%Y-%m-%d)
OUTPUT_DIR="route53_export_${DATE}"
# 出力ディレクトリを作成する関数
create_output_directory() {
if [ -d "$OUTPUT_DIR" ]; then
echo "警告: 既存ディレクトリが存在するため、タイムスタンプ付きで作成します"
OUTPUT_DIR="${OUTPUT_DIR}_$(date +%H%M%S)"
fi
mkdir -p "$OUTPUT_DIR"
echo "作成完了: $OUTPUT_DIR"
}
# Route53のホストゾーン情報をエクスポートする関数
export_hosted_zone() {
local zone_id=${1#/hostedzone/} # ゾーンIDからスラッシュを削除
local zone_name=${2%.} # 最後のドットを削除
echo "ホストゾーンの出力: $zone_name ($zone_id)"
# 安全なファイル名を生成
local safe_zone_name=$(echo "$zone_name" | tr -d -c '[:alnum:]._-')
local output_file="${safe_zone_name}_${zone_id}.json"
local temp_file=$(mktemp)
# ゾーン情報とレコードセットの取得
aws route53 get-hosted-zone --id $zone_id | jq '.HostedZone' > "$temp_file"
aws route53 list-resource-record-sets --hosted-zone-id $zone_id | \
jq '.ResourceRecordSets' | \
jq --slurpfile zone "$temp_file" '{
"hostedZone": $zone[0],
"records": .,
"exportDate": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"
}' > "$OUTPUT_DIR/$output_file"
rm "$temp_file"
echo "- 出力先: $OUTPUT_DIR/$output_file"
echo "- レコード数: $(jq '.records | length' "$OUTPUT_DIR/$output_file")"
}
# メイン処理
main() {
echo "Route 53のエクスポートを開始します..."
create_output_directory
# ホストゾーン一覧の取得
echo "ホストゾーン情報を取得中..."
zones=$(aws route53 list-hosted-zones --output json)
# ホストゾーンの処理
zone_count=$(echo "$zones" | jq '.HostedZones | length')
if [ "$zone_count" -eq 0 ]; then
echo "ホストゾーンが見つかりません"
exit 0
fi
echo "$zone_count 個のホストゾーンを検出"
echo "--------------------------------"
# 各ゾーンの処理
echo "$zones" | jq -c '.HostedZones[] | {Id, Name}' | while read -r zone; do
export_hosted_zone "$(echo "$zone" | jq -r '.Id')" "$(echo "$zone" | jq -r '.Name')"
done
echo "--------------------------------"
echo "エクスポートが完了しました!"
echo "出力ディレクトリ: $OUTPUT_DIR"
}
main
どういう処理を入れればいいか?
「ゾーン情報とレコードセットの取得」の処理で、出力前にjqで変換を入れてあげればOK
- 修正後のコード
aws route53 list-resource-record-sets --hosted-zone-id $clean_zone_id | \
jq '.ResourceRecordSets' | \
jq --slurpfile zone "$temp_file" '{
"hostedZone": $zone[0],
"records": .,
"exportDate": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"
}' | \
jq 'walk(if type == "string" then gsub("\\\\052"; "*") else . end)' \
> "$OUTPUT_DIR/$output_file"
最後に
文字コード系の処理は見落としやすいので、注意が必要ですね。
私はスクリプト作成して少し経ってから、人に言われて気づきました。。。
以降は注意していきたいと思います。
以上、どなたかのお役に立てば幸いです。