DATAセクション
配列やハッシュテーブルのようにデータを格納する方法ではないが、PowerShell Coreのスクリプトを読む上で欠かすことのできない「DATAセクション」という機能を紹介しておく。
DATAセクションは必ずしも使わなければならない機能ではないが、国際化対応しているPowerShell Coreスクリプトなどで使われている方法なので、 スクリプトを読むためにどういったものであるかを理解しておく必要がある。
DATAセクションはPowerShell Coreにおいてデータを文字列として記述することを可能にする機能。スクリプトにおいてもロジックとデータを分離することはコードの読みやすさや理解しやすさを向上させる点において意味がある。
PowerShell Coreでは主にテキストメッセージなどを国際化対応する方法としてこの機能が使われている。
DATAセクションの利用例
まず、DATAセクションを利用してどのようにPowerShell Coreスクリプトを記述するのか見てみよう。
次のPowerShell CoreスクリプトはmacOSで動作するように書いたPowerShell Coreのスクリプトだ。『DATA {』から『}』までがDATAセクションになっており、結果が変数$msgに代入されるというコードになっている。
SysExists.ps1 - DATAセクションを使ったPowerShell Coreスクリプトの例
#!/usr/local/bin/pwsh
$msg = DATA {
# Exit status codes for system programs
ConvertFrom-StringData @'
OK = Successful termination
USAGE = Command line usage error
DATAERR = Data format error
NOINPUT = Cannot open input
NOUSER = Addressee unknown
NOHOST = Host name unknown
UNAVAILABLE = Service unavailable
SOFTWARE = Internal software error
OSERR = System error
OSFILE = Critical OS file missing
CANTCREAT = Can't create output file
IOERR = Input/output error
TEMPFAIL = Temp failure
PROTOCOL = Remote error in protocol
NOPERM = Permission denied
CONFIG = Configuration error
'@
}
$msg
DATAセクションを使う場合にはConvertFrom-StringDataコマンドレットが欠かせない。ConvertFrom-StringDataコマンドレットは文字列として記述された鍵と値の組み合わせをハッシュテーブルに変換する処理を行う。
つまり、上記のように記述することで、文字列として書いたものをハッシュテーブルとして$msgに代入することができる。
このスクリプトを実行すると次のようになる。
SysExists_en.ps1の実行例
/Users/daichi/tmp$ ./SysExists_en.ps1
Name Value
---- -----
SOFTWARE Internal software error
NOUSER Addressee unknown
USAGE Command line usage error
PROTOCOL Remote error in protocol
IOERR Input/output error
TEMPFAIL Temp failure
OSERR System error
OSFILE Critical OS file missing
NOHOST Host name unknown
CONFIG Configuration error
NOINPUT Cannot open input
OK Successful termination
DATAERR Data format error
CANTCREAT Can't create output file
UNAVAILABLE Service unavailable
NOPERM Permission denied
/Users/daichi/tmp$
DATAセクションにはこれ以外の記述も含めることができる。詳しい使い方はいずれ取り上げるとして、DATAセクションを利用することでこんな風にデータをロジックから分離してまとめて書けるようになる、ということを覚えておいてもらえればと思う。
DATAセクションの利用例 - 国際化するための使い方
PowerShell Coreでは実際にはDATAセクションは国際化などの用途で使われるのだが、その例を見てみよう。まず、先ほどのスクリプトを次のように変更する。
SysExists.ps1 - 国際化対応版
#!/usr/local/bin/pwsh
Import-LocalizedData -BindingVariable msg
$msg
Import-LocalizedDataコマンドレットは国際化スクリプトを作成する際には欠かすことのできないコマンドレットで、決められたディレクトおよびファイル名で配置された国際化向けファイルからデータを読み取って変数に代入するといった処理を行ってくれる。よくわからないうちはこういう書き方をするものだと思っておけばよいと思う。
国際化データは次のような感じで決められたディレクトリに決められた名前で配置する。SysExists.ps1というファイル名にしてあるので、国際化対応の方のファイル名はSysExists.psd1とする。
そしてロケールごとにディレクトリを作成し、その下にSysExists.psd1というファイル名のデータファイルを置く。構造を見ると次のようになる。
国際化スクリプトの配置例
/Users/daichi/tmp$ tree
.
├── SysExists.ps1
├── en-US
│ └── SysExists.psd1
└── ja-JP
└── SysExists.psd1
2 directories, 3 files
/Users/daichi/tmp$
国際化スクリプトの中身は、例えば次のようになる。
英語用データファイル - en-US/SysExists.psd1
ConvertFrom-StringData @'
OK = Successful termination
USAGE = Command line usage error
DATAERR = Data format error
NOINPUT = Cannot open input
NOUSER = Addressee unknown
NOHOST = Host name unknown
UNAVAILABLE = Service unavailable
SOFTWARE = Internal software error
OSERR = System error
OSFILE = Critical OS file missing
CANTCREAT = Can't create output file
IOERR = Input/output error
TEMPFAIL = Temp failure
PROTOCOL = Remote error in protocol
NOPERM = Permission denied
CONFIG = Configuration error
'@
日本語用データファイル - ja-JP/SysExists.psd1
ConvertFrom-StringData @'
OK = 正常終了
USAGE = コマンドラインエラー
DATAERR = データフォーマットエラー
NOINPUT = インプットオープン不可能
NOUSER = 不明アドレス
NOHOST = 不明ホスト名
UNAVAILABLE = サービス不在
SOFTWARE = 内部ソフトウェアエラー
OSERR = システムエラー
OSFILE = OS関連ファイル不在
CANTCREAT = 出力ファイル作成不可能
IOERR = 入出力エラー
TEMPFAIL = 一時的な失敗
PROTOCOL = プロトコルにおけるリモートエラー
NOPERM = 不正パーミッション
CONFIG = 設定エラー
'@
日本語環境であれば日本語のデータファイルの中身が、英語環境であれば英語のデータファイルの中身が使われるという仕組みになっている。
例えば次のように環境変数LANGを設定してSysExists.ps1を実行すれば、英語データが使われる。
英語データが使われるケース
/Users/daichi/tmp$ env LANG=C ./SysExists.ps1
Name Value
---- -----
TEMPFAIL Temp failure
SOFTWARE Internal software error
UNAVAILABLE Service unavailable
USAGE Command line usage error
NOINPUT Cannot open input
NOUSER Addressee unknown
CONFIG Configuration error
NOPERM Permission denied
PROTOCOL Remote error in protocol
OSERR System error
NOHOST Host name unknown
CANTCREAT Can't create output file
DATAERR Data format error
IOERR Input/output error
OSFILE Critical OS file missing
OK Successful termination
/Users/daichi/tmp$
環境変数LANGをja_JP.UTF-8に設定すれば、次のように日本語データが使われるようになる。
日本語データが使われるケース
/Users/daichi/tmp$ env LANG=ja_JP.UTF-8 ./SysExists.ps1
Name Value
---- -----
NOPERM 不正パーミッション
SOFTWARE 内部ソフトウェアエラー
UNAVAILABLE サービス不在
CONFIG 設定エラー
NOUSER 不明アドレス
OSERR システムエラー
OK 正常終了
OSFILE OS関連ファイル不在
PROTOCOL プロトコルにおけるリモートエラー
CANTCREAT 出力ファイル作成不可能
NOHOST 不明ホスト名
NOINPUT インプットオープン不可能
IOERR 入出力エラー
USAGE コマンドラインエラー
TEMPFAIL 一時的な失敗
DATAERR データフォーマットエラー
/Users/daichi/tmp$
環境変数LANGをen_US.UTF-8にすると次のように英語データが使われるようになる。
英語データが使われるケースその2
/Users/daichi/tmp$ env LANG=en_US.UTF-8 ./SysExists.ps1
Name Value
---- -----
NOHOST Host name unknown
CANTCREAT Can't create output file
TEMPFAIL Temp failure
SOFTWARE Internal software error
OSERR System error
OSFILE Critical OS file missing
USAGE Command line usage error
IOERR Input/output error
DATAERR Data format error
NOPERM Permission denied
PROTOCOL Remote error in protocol
OK Successful termination
NOUSER Addressee unknown
NOINPUT Cannot open input
CONFIG Configuration error
UNAVAILABLE Service unavailable
/Users/daichi/tmp$
こんな感じでデータファイルを用意してあげれば、それに応じてデータが使われるようになる仕組みになっている。
PowerShell Coreスクリプトについてわからない方も、今回はひとまず、データを書く方法にDATAセクションというやり方があり、この機能はスクリプトを国際化するといった目的で使われる、ということを把握しておいてほしい。解説が進むにつれ、ピンとくることがあるはずだ。