PowerShellからWSL上のLinuxコマンドを呼び出すラッパーコマンドを試してみた

PowerShell Core

しばたです。

Windows Command Line Blogに面白い記事が投稿されていたので、本記事で軽く解説し公開されているスクリプトを試してみます。

Windows上でのLinuxコマンド

Windows上でLinuxコマンドを実行する方法はいろいろありますが、2019年現在はWindows Subsystem for Linux (WSL)がWindows 10(およびWindows Server 2019)で標準で利用可能です。
WSLでは様々なLinuxディストリビューション環境をサブシステムとして利用可能で、通常はコンソール(Bash)で対話的につかう事が多いかと思いますが、外部からwsl.exeを起動することで非対話的に利用することも可能です。

# コマンドプロンプトやPowerShellコンソールから wsl.exe を呼び出すことも可能
wsl.exe ls -al ~/ 

この機能を応用することでコマンドプロンプトやPowerShellコンソールからWSL内の各種Linuxコマンドを実行することが可能ですが、先述のブログに記載されている様に以下の問題を抱えています。

  • Linuxコマンドを実行するのにいちいちwsl.exeを記述するのはめんどうくさい
  • Windows上のパスに含まれるバックスラッシュをエスケープしなければならない問題
  • WSLで表現されるWindowsパス(/mnt/c/など)の相互変換
  • WSLのログインプロファイルにあるエイリアスや環境変数が反映されない
  • Linuxパスの補完がサポートされていない
  • コマンド名補完がサポートされていない
  • コマンド引数の補完がサポートされていない

このためコマンドプロンプトやPowerShellのデフォルトではWSLのLinuxコマンドを利用するのは地味に面倒です。

WSL上のLinuxコマンドを呼び出すラッパーコマンドを試してみた

この面倒さを解消するために、先述のブログではPowerShellで書いたラッパー関数を公開し、GitHub上でメンテナスしています。

関数内部の解説については先述のブログをご覧いただくとして、以下のコードをPowerShellコンソール上で実行するとPowerShellからWSLのコマンド(awk, emacs, grep, head, less, ls, man, sed, seq, ssh, tail, vim)が利用可能になります。
前提条件としては、

  • WSLの正式版(wsl.exeでWSLを呼び出せるバージョン。Windows 10 Fall Creators Update(1709)以降)がインストール済みであること
  • PowerShell Core 6.0以降
    • 内部でRemove-Aliasを使っているため。改造すればWindows PowerShellでも利用可能な気はします...

となり、本記事ではWindows 10 May 2019 Update(1903)+PowerShell Core 6.2.3で試しています。

# PowerShell Coreでのみ利用可能

# ここではGitHubからスクリプトファイルの内容を読み込み実行していますが、ファイルの内容をプロファイルに転記する方法もアリ
Invoke-Expression (Invoke-RestMethod -Uri https://raw.githubusercontent.com/mikebattista/PowerShell-WSL-Interop/master/PowerShell%20WSL%20Interop.ps1)
# 実行したいWSLのコマンドをインポート
Import-WslCommand "awk", "emacs", "grep", "head", "less", "ls", "man", "sed", "seq", "ssh", "tail", "vim"

上記コマンドを実行すると下図の様にPowerShellコンソール上でWSLのコマンドを割と自然に利用することができます。

WSLのパスおよびWindowsのパスを横断的に指定可能で、また、パスや引数の補完も利きます。

最後に

ざっとこんな感じです。
都度wsl.exeを起動する形をとるので若干の"重さ"はありますが、PowerShell上でawkgrepsedといった三種の神器が使えるは非常に便利に感じました。
普段Windowsを使っていてLinuxコマンドが使えないと不満を感じている方はぜひこのラッパーコマンドを試してみてください。