WEBサイト、ホームページ制作の現場では、サーバーを切り替えて動作チェックをすることが多くあります。
そのときにMacの /etc/hosts ファイルを変更するのですが、これが意外と手間なんですよね。
それが、Claude Codeでめっちゃ簡単にできました。
バックアップから後片付けまで入ったスクリプトを作ってくれまして。しかも1回失敗したのですが、その原因までClaude Codeが見つけてくれた、という話です。
やっていることは、スクリプトを自動で書いてもらって、指示されたコマンドをシェルに貼り付けて実行するだけ。
楽ちんです。
Claude Codeだと、スクリプトをMacのローカルに書いてくれるので、実行するだけでOK。これが楽ちんです。
この記事の値は、実際のものではなく例示用のもの(example.com と 203.0.113.10)に置き換えて書いています。
Claude Codeに頼んだのは、この一言だけ
打ち込んだのは、これだけ。
mac の host 一時的に example.com を 203.0.113.10
「hosts」を「host」と打ち間違えているし、「〜に向けて」も抜けています。
それでも、ちゃんと通じました。
sudoが必要なので、Claude Codeは実行できない
/etc/hosts の書き換えにはroot権限が要ります。
Claude Codeはパスワードを打てないので、実行だけは自分でやることになります。
で、出てきたのが「スクリプトを作ったので、これを実行してください」という形。
渡されたのは、この1行だけでした。
sudo bash ~/scripts/hosts-temp.sh add
スクリプトの中身
こちらです。パスやドメインは自分の環境に合わせて書き換えてください。
#!/usr/bin/env bash
set -euo pipefail
DOMAIN="example.com"
IP="203.0.113.10"
MARK="# temp-hosts"
HOSTS="/etc/hosts"
ACTION="${1:-add}"
if [ "$(id -u)" -ne 0 ]; then
echo "エラー: root 権限が必要です。次のように実行してください:"
echo " sudo bash $0 ${ACTION}"
exit 1
fi
# 正規表現用にドットをエスケープ
IP_RE="$(printf '%s' "$IP" | sed 's/\./\\./g')"
DOM_RE="$(printf '%s' "$DOMAIN" | sed 's/\./\\./g')"
STAMP="$(date +%Y%m%d-%H%M%S)"
echo "[1/5] バックアップ作成: ${HOSTS}.bak.${STAMP}"
cp -p "$HOSTS" "${HOSTS}.bak.${STAMP}"
echo "[2/5] 既存行に連結してしまった一時エントリを分離"
sed -i '' -E "s/^(.+[^[:space:]])[[:space:]]*${IP_RE} (www\.)?${DOM_RE} ${MARK}\$/\1/" "$HOSTS"
echo "[3/5] 一時エントリ行を削除"
sed -i '' -E "/^${IP_RE}[[:space:]].*${MARK}\$/d" "$HOSTS"
case "$ACTION" in
add)
echo "[4/5] エントリ追加: ${IP} ${DOMAIN} / www.${DOMAIN}"
# 末尾に改行がなければ補う
if [ -n "$(tail -c 1 "$HOSTS")" ]; then
printf '\n' >> "$HOSTS"
fi
{
echo "${IP} ${DOMAIN} ${MARK}"
echo "${IP} www.${DOMAIN} ${MARK}"
} >> "$HOSTS"
;;
del|remove)
echo "[4/5] 削除のみ実行"
;;
*)
echo "使い方: sudo bash $0 [add|del]"
exit 1
;;
esac
echo "[5/5] DNS キャッシュをフラッシュ"
dscacheutil -flushcache || true
killall -HUP mDNSResponder 2>/dev/null || true
echo "--- /etc/hosts の末尾 ---"
tail -6 "$HOSTS"
echo "--- 名前解決の確認 ---"
dscacheutil -q host -a name "${DOMAIN}"
ping -c 1 -t 2 "${DOMAIN}" 2>&1 | head -2 || true
こんな長いスクリプトを書くのは、自分は面倒です。でもClaude Codeはすぐにやってくれます。素晴らしい。
やっていることは、この5つです。
/etc/hosts.bak.20260802-143022の形でバックアップを取る- 一時エントリを追加(または削除)する
- DNSキャッシュをフラッシュする
- 書き換え後の
/etc/hostsを表示する - 名前解決の結果まで確認する
気に入ったのが、追加する行のうしろに # temp-hosts というマーカーを付けているところ。
203.0.113.10 example.com # temp-hosts
203.0.113.10 www.example.com # temp-hosts
このマーカーが付いた行だけを消す作りになっているので、ローカル開発環境が書いた行や、昔から入れっぱなしの行を巻き込む心配がありません。
/etc/hosts はシステムの根っこにあるファイルなので、当然ながら自己責任になります。バックアップは必ず取ってから実行してください。
「切り替わっている?」と聞いたら、切り替わっていなかった
実行して、Claudeに聞いてみました。
「切り替わっている?」
調べに行って、返ってきたのが、
切り替わっていません、と。
こんな出力でした。
=== /etc/hosts ===
24:## Local - End ##203.0.113.10 example.com # temp-hosts
25:203.0.113.10 www.example.com # temp-hosts
=== dscacheutil ===
name: example.com
ip_address: 198.51.100.20
=== ping ===
PING example.com (198.51.100.20): 56 data bytes
24行目。
## Local - End ## のうしろに、追加したはずの行がくっついています。
ここでハマりました。原因は、hostsの末尾に改行がなかったこと
元の /etc/hosts の最終行に、改行が入っていなかったんですね。
そこに >> で追記したので、1行目が既存の行の続きとして書き込まれてしまった。
# で始まる行はコメント扱いなので、## Local - End ##203.0.113.10 example.com は丸ごと無視されます。だから example.com は元のIPのまま。
2行目の www.example.com は独立した行になっていたので、そっちだけは効いていた、という状態でした。
目で見てもパッと気づきにくいやつです。
これを、Claudeが ping と dscacheutil の結果を並べて「ここが原因です」と持ってきました。僕は行番号付きの出力を眺めて「あっ」と言っただけ。
修正もお願いするだけで終わりまして、スクリプトに、
- 追記の前に末尾の改行を確認して、なければ足す
- すでに連結してしまった行から、追加分だけを切り離す
の2つが入って、上に載せたバージョンになりました。
今回、コードは1行も書いていません。全部、話し言葉で頼んだだけ。すごい時代になったなと思います。
戻すのも一言
確認が終わったら、del を付けて実行するだけ。
sudo bash ~/scripts/hosts-temp.sh del
マーカーの付いた行だけが消えて、## Local - End ## にくっついてしまった分も元通りになります。
戻し忘れが一番こわいので、ここが1コマンドなのはありがたいです。
(そのうち「確認が終わったら自動で戻す」みたいなのも頼めそうだな、と思っています。まだやっていないですけど)
まとめ
/etc/hostsの一時変更は「バックアップ」「既存行を壊さない」「DNSキャッシュを消す」「戻す」の4つが地味に面倒- その4つを全部入れたスクリプトを、話し言葉のお願い1回で作ってもらえた
- うまくいかなかったときに、その場で原因まで調べてくれるのが一番ありがたい
あと、切り替えたあとの確認はシークレットウィンドウでどうぞ。ブラウザは独自にキャッシュを持っているので、hostsを直しても古いほうを見に行くことがあります。
※リンクはAmazonアソシエイト・プログラムを利用しています







