【PowerShell小ネタ】 PowerShellのmoreとUNIXコマンドのmoreは別物!

【PowerShell小ネタ】 PowerShellのmoreとUNIXコマンドのmoreは別物!

UNIXコマンド感覚で使うと危険

ちょっと前、ヒヤっとすることがあったので備忘を兼ねてメモ。

ある日、出社すると社内の開発機(Windows Server 2016)の非システムドライブの空き容量が十数GBになっていた。
何事かと思って中身を確認してみると、開発中のアプリが1日につき数GBものログを吐き出しているよう。
すぐに止めてもらわなきゃ困るのだけど、担当者が分からないしとりあえず中身を見てみよう…

そうだ、PowerShellってlessはないけどmoreが使えるよね、
と思って more (ログファイル名) と入力しエンター。

ところが、1秒ほど経ってもレスポンスが帰ってこない。
嫌な予感がしてタスクマネージャを開いてみると、予想通り空きメモリがぐんぐん減っていっている。
急いでCtrl + Cで停止。危ない危ない。
※まあ、たかだか社内開発機なのでメモリ枯渇させても関係者から顰蹙を買うだけで済む

何が起こったのかというと…
UNIXコマンドのmoreやlessは、ファイル全体をメモリに乗せずに表示分だけを読み込む。
ところが、PowerShellのmoreはUNIXのcatのように最初にファイル全体をメモリに乗せてしまうよう。
これは酷い罠。同じ名前なのに挙動が全然違う。

ところで、PowerShellのmoreって何のエイリアス?と思ってGet-Aliasで調べてみると該当なし。
エイリアスではないよう。
Get-Commandで中身を見てみると次の通り。
組み込みの関数だったのね。

----
              param([string[]]$paths)
              $OutputEncoding = [System.Console]::OutputEncoding
              if($paths) {
                  foreach ($file in $paths)
                  {
                      Get-Content $file | more.com
                  }
              } else { $input | more.com }
----

…うん。これアレだ。
実態はただの C\Windows\System32\more.com じゃないか!

PowerShellで巨大なテキストを読み込む方法

moreがダメなことは分かった。
じゃあ、PowerShellでmoreっぽく巨大なテキストを開くにはどうしたらいいのか。

ちょっと試してみたら、次の方法で大丈夫だった。

     Get-Content (巨大なテキストファイル) | Out-Host -Paging

Out-HostのPagingオプションでmoreっぽい挙動になるし、
この方法なら対象ファイルを一気にメモリに乗せてしまうこともない。

さらに調べてみると、PowerShell v1.0ではmoreの中身は Out-Host -Pagingであったよう。
どうして変えてしまったのか…

0 件のコメント :

コメントを投稿