はじめに (対象読者・この記事でわかること)

このガイドは、Linux環境で script コマンドを用いてターミナル操作を記録する開発者・サーバー管理者を対象としています。
script が出力するログファイルはデフォルトでは端末の現在の文字コードで保存されるため、UTF-8 以外のロケールや特殊文字が混在すると文字化けが起こりやすくなります。
本記事を読むことで、文字化けの原因を正しく理解し、UTF-8 で安全にログを取得・閲覧できる 方法が身につきます。実務でトラブルシューティングに時間を取られることなく、効率的にデバッグ情報を活用できるようになります。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。

  • 基本的な Linux コマンド操作(catlessvim など)
  • ロケールと文字コード(特に UTF-8、ISO-2022-JP、Shift_JIS)の概念
  • Bash シェルの基本的な使い方

scriptコマンドと文字化けの背景

script コマンドは端末の入出力をそのまま記録するツールで、script -a logfile のように使うと標準出力と標準エラー出力をすべて logfile に書き込みます。このとき、端末が現在使用しているロケール($LANG)に従ってバイト列が保存されます。

日本語環境で多く見られるのは LANG=ja_JP.UTF-8 ですが、SSH でリモートサーバに接続したときや、Docker コンテナ内部でロケールが C(ASCII)や ja_JP.eucJP になるケースがあります。その結果、UTF-8 で書き込むべき箇所が別のエンコーディングで保存され、catless で閲覧すると文字化けが発生します。

文字化けは主に次の二つの要因で起こります。

  1. 記録時のエンコーディングが期待と異なる
    - 端末側が UTF-8 でなく、Shift_JIS 等で出力された場合
  2. 閲覧時の環境が記録時と合っていない
    - ローカルのターミナルが UTF-8 でも、ログが EUC-JP で保存されているケース

これらを防ぐには、記録時に明示的に UTF-8 を使用させ、閲覧時に同じエンコーディングでデコード することが基本です。

文字化けを防ぐ具体的な手順

以下では、サーバ側とクライアント側の両方で行う設定例を示し、実際に文字化けしないログファイルを取得するまでの流れをステップごとに解説します。

ステップ1 ― ロケールを統一する

1‑1. サーバ側ロケールを UTF-8 に設定

Bash
# /etc/locale.conf もしくは /etc/default/locale に以下を追記 LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 # 設定反映 source /etc/locale.conf # または `export LANG=en_US.UTF-8`

Docker コンテナ内の場合は、Dockerfile に次の記述を追加します。

Dockerfile
ENV LANG=C.UTF-8 ENV LC_ALL=C.UTF-8

1‑2. SSH 接続時にロケールを引き継ぐ

/etc/ssh/sshd_configAcceptEnv LANG LC_* が有効か確認し、クライアント側の ~/.ssh/config にも同様の設定を追加します。

Ssh
# sshクライアント側 (例) Host * SendEnv LANG LC_*

これにより、SSH 接続時にローカルの UTF-8 ロケールがサーバ側に伝搬され、script が UTF-8 で記録できるようになります。

ステップ2 ― script のオプションでエンコーディングを強制

script 自体にエンコーディング指定はありませんが、scriptreplay と組み合わせたり、stdbuficonv をパイプで挟むことで対処できます。

2‑1. script + iconv で即座に変換

Bash
script -q -c "your-command" -a >(iconv -f $(locale charmap) -t UTF-8 > ~/log_utf8.txt)

上記は、script が内部で使用しているロケール ($(locale charmap)) を自動取得し、UTF-8 に変換した上で log_utf8.txt に保存します。

2‑2. script -e (exit on error) と script -q の併用

Bash
script -e -q -a ~/log_raw.txt

このコマンドはエラーが発生した瞬間に終了し、余計な制御文字が入りにくくなるため、後処理での文字化けリスクが低減します。

ステップ3 ― ログの確認と文字化けの検証

3‑1. file コマンドでエンコーディングを確認

Bash
file -i ~/log_utf8.txt # 出力例: ~/log_utf8.txt: text/plain; charset=utf-8

3‑2. less -R で安全に閲覧

Bash
LESSCHARSET=utf-8 less -R ~/log_utf8.txt

-R オプションは ANSI エスケープシーケンスを保持しつつ色付き出力を可能にし、UTF-8 文字が正しく表示されます。

ハマった点やエラー解決

問題 1 ― iconv が「illegal input sequence」と出力

  • 原因: script が端末のロケールと違う文字コードで出力しているケース(例: C ロケール → ASCII)。
  • 解決策: script 実行前に export LANG=en_US.UTF-8 を明示的に設定し、再度実行。

問題 2 ― less で文字化けが残る

  • 原因: LESSCHARSET がシステムデフォルトの latin1 になっている。
  • 解決策: 環境変数 LESSCHARSET=utf-8 を永続化(~/.bashrc に追記)し、端末を再起動。

問題 3 ― Docker コンテナ内で script が無効

  • 原因: scripttty デバイスを必要とするが、docker run のデフォルトでは tty が割り当てられない。
  • 解決策: docker run -it オプションで擬似端末を確保し、ロケールも同様に ENV LANG=C.UTF-8 を設定。

解決策のまとめ

  • ロケール統一: サーバ・クライアント双方で UTF-8 を明示的に設定
  • script とパイプ: iconv でリアルタイム変換、もしくは scriptreplay で再生時に変換
  • 閲覧環境: LESSCHARSET=utf-8file -i でエンコード確認し、UTF-8 用ツールで開く

これらを組み合わせるだけで、script が生成するログは文字化けせず、後続の解析ツール(awkgrepsed など)でも問題なく扱えるようになります。

まとめ

本記事では、script コマンドで取得したログが文字化けする典型的な原因と、ロケール統一・リアルタイムエンコード変換・閲覧設定 の3つの対策を中心に解説しました。

  • ロケールを UTF-8 に統一 することで、記録時のエンコード不一致を防止
  • iconv とパイプ を使い、記録直後に UTF-8 に変換
  • 閲覧ツール側の設定LESSCHARSET etc.)を合わせて、正しく表示

これにより、UTF-8 環境でのデバッグやログ分析がスムーズになり、文字化けに悩む時間を大幅に削減できます。次回は、取得したログを自動的に ElasticSearch へ流し込み、可視化する手順について解説予定です。

参考資料