カタカタブログ

SIerで働くITエンジニアがカタカタした記録を残す技術ブログ。Java, Oracle Database, Linuxが中心です。たまに数学やデータ分析なども。

Linux上でシェルスクリプトをSJISで実行する

Linux上でシェルスクリプトをSJISを文字化けなく実行・表示するためには以下の点に注意する。※この注意点はSJISに限らず、他の文字コードであっても統一しておく必要がある。

  • ソースコードの文字コードをSJISにする
  • LANG環境変数をSJISにする。
  • 端末(Windowsの場合はTeraTerm等)の文字コードをSJISにする

上の3つ全て満たされてないSJISのシェルスクリプトは文字化けするだけでなく、下手をすると実行時エラーを引き起こす可能性がある。例えば"義"という文字はSJISだとバッククオート(`)となり、シェル実行時エラーとなるよう。

そこで、”義”という文字列をechoで標準出力するだけのシェルスクリプトを文字コードがUTF-8、SJISにしたものをそれぞれ用意して検証してみる。なお、今回後でlocaleを変更する都合上、全てrootユーザでコマンドを実行している。

LANG=ja_JP.utf8のとき、UTF-8のソースは正しく表示される。

# cat utf8_echo.sh
#!/bin/bash
echo "義”

一方、SJISのコードは改行+バッククオート(`)になってしまう。

# cat sjis_echo.sh
#!/bin/bash
echo "
      `"

実行するとUTF-8は当然正しく表示される。

# ./utf8_echo.sh
義

SJISのコードは実行時エラーとなる。

# ./sjis_echo.sh
./sjis_echo.sh: line 2: unexpected EOF while looking for matching ``'
./sjis_echo.sh: line 4: シンタックス エラー: 期待してないファイルの終了

これを正しく実行するためにLANGをSJISに変更する。

まず、現在のLANGを確認する。デフォルトのja_JP.UTF-8になっているはず。

# echo $LANG
ja_JP.UTF-8

続いて、localeにja_JP.sjisが存在するか確認する。

# locale -a | grep ja
ja_JP
ja_JP.eucjp
ja_JP.ujis
ja_JP.utf8
japanese
japanese.euc

Cent OS6では、デフォルトでja_JP.sjisがないようなので、SJISロケールを以下のコマンドで追加する。

# localedef -f SHIFT_JIS -i ja_JP ja_JP.SJIS
キャラクタマップ `SHIFT_JIS' は ASCII 互換ではありません, ロケールは ISO C に従 っていません
# echo $?
0

警告が出るが、特に問題なし。localeコマンドでja_JP.sjisが追加されていることを確認する。

# locale -a | grep ja
ja_JP
ja_JP.eucjp
ja_JP.sjis ★追加されている
ja_JP.ujis
ja_JP.utf8
japanese
japanese.euc

LANGをja_JP.sjisにexportする(.bashrcに書いても良い)。

# export LANG=ja_JP.sjis

この状態で、先ほどのSJISのシェルスクリプトを実行する。

# ./sjis_echo.sh
義

正しく実行・表示できた!一方UTF-8のシェルスクリプトは・・・

# ./utf8_echo.sh
鄒ゥ

こちらは当然だが文字化けして表示されている。

ちなみに、WindowsにてTeraTerm等のターミナルを使用している場合は、ターミナルの文字コードをSJISにしておかないと文字化けして表示される。
f:id:osn_th:20140922070634p:plain

以上