「PowerShell」はタスクの自動化や構成管理のためのプラットフォームとしてMicrosoftが開発しているスクリプト言語およびそのコマンドラインインターフェースプログラムです。今回紹介するのは、先日FLOSSとして公開されたこのPowerShellをUbuntuで使うです。
PowerShell 「Core」
Windowsの伝統的なCLIシェルと言えばコマンドプロンプト(cmd.exe)が存在します。PowerShellは、単にシェルとしてこのコマンドプロンプトを置き換えるだけでなく、より広範囲のシステム設定へのアクセスや.NET Frameworkを用いた柔軟な拡張性、パイプを用いたオブジェクトの操作、スクリプトの開発環境などなど、その機能の豊富さによってWindowsの管理には欠かせないツールとなっています。実際、PowerShellなしには生きられない体になったシステム管理者の方も多いことでしょう[1]。
先日のUbuntu Weekly Topicsでも紹介しているように、MicrosoftがそのPowerShellをFLOSSとしてGitHub上に公開しました。2016年8月時点ではまだアルファ版という扱いです。しかしながら単に「ソースコードを公開した」だけではなく、ライセンスがMIT Licenseであり、ソースコードの改修も積極的に受け入れるなど、FLOSSとしての条件が整った上での公開です。もちろんLinux上でも動作します。おそらく将来的には、Debianパッケージとして公式リポジトリからインストールできるようになるはずです[2]。
PowerShellは.NET Frameworkベースのソフトウェアです。それに対して今回GitHub上に公開された「PowerShell Core」は、.NET Frameworkをモジュール化したサブセットである.NET Coreを利用したソフトウェアになっています。つまりPowerShellのフルセットではない、ということは注意しておいてください。たとえばグラフィック関連のオブジェクト操作の機能などがありません。このPowerShell Coreは、コンテナでも使うことを想定したコンパクト版のWindows Serverである「Nano Server」にも搭載される予定です。またWindows以外では、当然のことながらWMI(Windows Management Instrumentation)関連の操作も行えません。
Debファイルをインストールするだけ
実際にPowerShellをインストールしてみましょう。といってもGitHub上に公開されているDebファイルをインストールするだけです。DebファイルはUbuntu 14.04 LTS用とUbuntu 16.04 LTS用の両方が存在します。本Recipeでは、16.04で使用することを前提に説明します。
まずリリースページを参考に、最新のDebファイルをダウンロードします。
Debファイルをインストールしたら、すぐにインストールせずにまずは中身を確認することにしましょう[3]。dpkg-debコマンドはDebファイルの内容を確認できるツールです。たとえば「--info」オプションを渡すと、「apt show」で表示されるようなメタデータが表示されます。特に注意すべきは「Depends」や「Recommends」です。これらのフィールドに表示されているパッケージは、このDebファイルにとって必要なパッケージとなります。下記の例だと「libunwind8」と「libicu55」に依存しているということです。libunwind8はプログラムのコールチェインを操作するためのライブラリです。デスクトップ版のUbuntuなら最初からインストールされています。libicuはUnicode対応のために使われるライブラリで、こちらはすべてのエディションのUbuntuに最初からインストールされています。
「--contents」オプションを使うと、そのパッケージのインストールパスを確認できます。PowerShellの場合は、基本的に「/opt/microsoft/」以下にインストールし、マニュアルやパッケージの変更履歴、実行ファイルへのシンボリックリンクなどを標準的な場所にインストールするようです。ちなみにインストール済みのパッケージであれば「dpkg -L パッケージ名」で同等の情報を取得できます。
Debianパッケージは、パッケージが提供するコンテンツとは別に「コントロールファイル」と呼ばれる、パッケージの操作に必要なスクリプト群を「/var/lib/dpkg/info/」以下にインストールします。そのファイルのリストは「--control」で確認できます。PowerShellの場合は、パッケージのメタデータであるcontrolファイルと、コンテンツのハッシュ値が格納されたmd5sumsファイルのみインストールします。パッケージによっては「postinst」や「prerm」といった、インストールや削除前後に実行するスクリプトがインストールされることもあります。
Debファイルの中身に不審な点がなければ、パッケージをインストールしましょう。Ubuntu 16.04 LTSのaptコマンドは、相対パスでDebファイルを渡せば依存パッケージまでインストールしてくれるので便利です。なお「./」を指定しないとパッケージファイル名ではなくパッケージ名として判断してしまうので注意してください。
Ubuntu 14.04 LTSなら、dpkgコマンドでインストールしたのちにapt-getコマンドで依存関係を解決すると良いでしょう。
うまくインストールできたらPowerShellを起動してみましょう。
とっても簡単でしたね。
PowerShellの基本のキ
PowerShellは単体で動かすと、ごく普通のCLIシェルプログラムです。プロンプトが表示され、コマンドを入力し、ディレクトリの移動やファイルの操作、各種プログラムの呼び出しを行います。PowerShellに組み込まれた一定の命名規則に従った命令を「コマンドレット」と呼びます。単なる組み込みコマンドというわけではなく、ユーザーがコマンドレットを追加することも可能です。またシェルなのでコマンドレットだけでなく、システムに存在する実行ファイルをコマンドとして実行できます。たとえばPowerShell上でBashを実行することももちろん可能なのです。
コマンドレットは「動詞-名詞」という命名規則をもっています。必ずしもすべてが命名規則に従っているわけではありませんし、コマンドレット以外も同じような名前が付いている場合もあります。現在のセッションで利用できるコマンドレット一覧は、「Get-Command」で取得できます。また、ワイルドカードも使えます。なおすべて小文字でも問題ありません。
タブ補完もサポートしているので、とりあえず「Get」を入力してタブを押せば、何らかのオブジェクトを取得できるコマンドの一覧をリストアップできるというわけです。
特定のコマンドのヘルプは「Get-Help」で確認できます[4]。
PowerShellにもエイリアス機能があります。たとえばディレクトリを移動する「Set-Location」には「sl」というエイリアスがついています。つまり、PowerShell環境では残念ながらslコマンドを実行しても、カレントディレクトリがホームディレクトリになるでSLは走ってくれません。どうしてもSLを走らせたい場合は、「/usr/games/sl」とフルパスで実行してください[5]。
エイリアスの一覧は「Get-Alias」で取得できます。また「Set-Alias」でエイリアスを作成・変更できます。組み込みエイリアスは比較的使用頻度の高いコマンドの一覧でもあるため、一度ながめておくとPowerShellのコマンドレットの雰囲気がわかることでしょう。
変数や制御構造、リダイレクト、パイプといった機能は他のシェルスクリプトと同じように利用できます。しかしながらPowerShellでは、すべてをオブジェクトとして扱います。パイプもオブジェクトを次のコマンドレットに渡すのです。雰囲気としてはBashよりも、Pythonなどのオブジェクト指向言語に近いでしょう。たとえばpsコマンドを使ってプロセスツリーを表示することは、Bashと同じです。
しかしながら「Get-Process」を使うと特定のプロセスのProcessオブジェクトを取得した上で、さらにそのプロセスの詳細をメソッドを用いて出力できます。
さらに「New-Object」などを使うことで.NETのクラスを使用したインスタンスを生成できます。とりあえず「PowerShellはその名の通りかなり強力な言語」ということだけ覚えておいて、詳しいことはPowerShellのドキュメントや各種解説サイトを参照してください。
PowerShellをビルドする
ソースコードが公開されているので、もちろんリポジトリの最新のコードをビルドして試すことも可能です。Ubuntu 14.04 LTSとUbuntu 16.04 LTSのどちらでもビルドできます。PowerShellのビルドには.NET CoreのCLIツールが必要です。こちらもUbuntu用のバイナリが存在します。またビルドシステムはCMakeを使っています。パッケージを作る場合は、Ruby gemのfpmを使用しているようです。
まずはPowerShellのソースコードをクローンします。「--recursive」オプションを指定するとsubmoduleも一緒にクローンしてくれるので便利です。ちなみにsubmoduleとして使用しているのは、Google製のC++テストフレームワークであるGoogle TestとPowerShell用のテストフレームワークであるPesterをクロスプラットフォーム向けに一時的にフォークしたものの2つです。
まずはビルドに必要なパッケージやツールをインストールします。といってもPowerShellのソースコードにはそれを実行するためのPowerShellスクリプトモジュールが存在します。つまりPowerShellをビルドするなら、まずはじめにPowerShellをインストールしておいた方が楽です。もちろんスクリプトモジュールと同じ内容のコマンドを実行すれば、あらかじめPowerShellをインストールする必要はありません。もし、未インストールなら次のスクリプトを実行しましょう。OSに応じて処理が変わるようになっていますが、内容的には本Recipeの前半で説明したことと同じです。
以降はPowerShellを用いたビルド方法を説明します。PowerShellを起動した上で、ソースディレクトリの中で次のコマンドを実行します。
もしくはpowershellコマンドから直接スクリプトモジュールを読み込んで実行する方法でもかまいません。
PowerShellのスクリプトファイルは、拡張子に「.ps1」を指定することが一般的です。それに対して「.psm1」は、他のPowerShellスクリプトから再利用可能なスクリプトや関数の集合体で、「Import-Module」で取り込んでからモジュール内の関数を実行します。
「Start-PSBootstrap」関数では、主に以下のような作業を行います。
内部的に「sudo」コマンドを使っているため、必要に応じてパスワード入力が発生します。また、.NET CLI関連は「~/.dotnet/」以下にインストールされます。
さて、ようやく実際のビルド作業に入ります。こちらもPowerShellスクリプトを実行するだけです。
もしくはpowershellコマンドから直接スクリプトモジュールを読み込んで実行する方法でもかまいません。
ちなみにPowerShellのソースコードに含まれる、build.shも上記と同じことを実施していますので、何度もビルドを繰り返すならこちらを使うと良いでしょう。
しばらく待てばビルドが完了します。ビルドされたPowerShell本体は以下のパスに存在しますので、実際に起動してみましょう。
パッケージを作りたい場合は、パッケージフラグを有効化した上でStart-PSBootstrapを実行します。これでRubyなどがインストールされます。ただしgemのインストール時にエラーとなってしまうようです。
そこで別途手動でgemをインストールします。ここではsudoを使って/var/lib/gems/以下にインストールしていますが、PowerShellから見える場所であればどこでもかまいません。
gemをインストールできたら、Publishフラグを有効化して再ビルドした上で、Start-PSPackageでパッケージを作成します。なお、再ビルド時に前回ビルドしたpowershell上、つまり「./src/powershell-unix」以下のpowershellで実行しようとするとファイルが使用中のため再ビルドできないので注意してください。
あとはカレントディレクトリに作られたパッケージファイルを本Recipeの最初に説明した方法でインストールすれば、システムのpowershellが最新版になります。