コマンドラインシェルの用途は2つ在る。対話的に処理させる場合と、バッチ処理させたい場合だ。バッチ処理用に起動した場合に、対話的環境での利用を想定した処理を行うのは無駄だ。例えばPowerShellでの場合、バッチ処理時にPowerTabモジュールを導入するのは意味がない。むしろ、その為の処理リソースを取られる事になるので、出来る限り避けたい。
PowerShellが対話的に動いているかどうかを判定する専用の方法というのは、調べてみたが見つけられなかった。しかし、powershell.exeのコマンドラインオプションに「-NonInteractive
」という物が在り、曰く"ユーザーに対話的なプロンプトを表示しません。"との事。これの有無で処理を分けるのが妥当なのだろう。結果的に、以下のどちらかの条件を満たしている時は、非対話的実行だと思って良さそうだ。
-NonInteractive
コマンドラインオプションが指定された-Command
オプションが指定され、且つ、-NoExit
オプションが指定されていない
というわけで作ったのが以下。$profileが指しているファイルの中に書いて利用する事を想定している。
function script:isInteractiveEnvironment {
$ps = (Get-WmiObject -Class win32_process -Filter "ProcessID=$PID")
$opts = -split ($ps.CommandLine -replace '^"?[^"]+"?\s+', '')
return -not ($opts -contains "-NonInteractive") `
-or (($opts -contains "-Command") -and ($opts -contains "-NoExit"))
}
$PIDには、そのPowerShell環境のプロセスIDが格納されている。
isInteractiveEnvironment
関数の戻り値がTrue
ならば対話的環境、False
ならば非対話的環境って事で、以下のようにすれば良い感じ。
Import-Module (常時読み込みたいモジュール)
# ...
if(isInteractiveEnvironment) {
Import-Module (対話環境時に読み込みたいモジュール)
# ...
} else {
Import-Module (非対話環境時に読み込みたいモジュール)
# ...
}