コマンドとは?
PowerShell Coreを使い始める最初の段階では、まず「コマンド」について理解しておく必要がある。
コマンドは、処理の単位と考えていただければよいだろう。シェルにおけるコマンドと同じようなもので、PowerShell Coreには代表的なものとして次の種類が用意されている。
- コマンドレット
- 関数
- エイリアス
- アプリケーション
インタラクティブに動作するpwsh(PowerShell Coreの本体であるpwsh.exe)で、何らかの処理をさせるために行の最初に入力するのがコマンドだ。コマンドを入力すると、その実行結果が返ってくる。
コマンドレットも関数もアプリケーションも見た目では区別がつかないが、実装上はちゃんと区別されている。最初にこのあたりの違いを覚えておこう。
コマンドレット
コマンドレットはPowerShell Core内部に実装された機能で、永続性があり、クラスとして実装されたものを指す。シェルでいうところの組み込みコマンドに近い。
例えばPowerShell Coreではカレントディレクトリを移動する処理はSet-Locationというコマンドレットで実行するのだが、これはPowerShell Coreの内部で実装されている。カレントディレクトリの移動はシェルそのもので実装する必要があるもので、コマンドレットというかたちがとられている。
実装を調べてみると、Set-Locationはクラスとして実装されていることがわかる。
本連載では、今後、PowerShellの実装そのものをたびたび取り上げることになるだろう。PowerShell Coreとしてソースコードが公開されたので、ドキュメントを読むよりもソースコードを読んだ方がわかりやすいことが多いためだ。
関数
コマンドレットとよく似たものに関数がある。
関数とは、コマンドレットのようにPowerShell Core内でクラスとして実装されたもの”以外”の処理と考えればよいだろう。
例えば、Clear-Hostというコマンドは関数として実装されている。ターミナルをクリアするコマンドだ。次のようにClear-Host関数を実行するとターミナルがクリアされる。
Clear-Hostの実装を調べていくと、PowerShell内部で関数として実装されていることがわかる。
関数はPowerShellの機能を使って後から追加することもできる。例えば、次のように実行するとSay-Helloという関数が定義され、コマンドとして実行できるようになる。
このように関数には2つの側面がある。
一つは、PowerShellの内部で実装されているものの、クラスとしては実装されていないもの。もう一つは、PowerShellスクリプトやインタラクティブ経由で定義して利用するものだ。
PowerShell内部に実装されているものはPowerShellを再起動しても利用できるが、スクリプトやインタラクティブで入力した関数はPowerShellを再起動すると消えてしまうという違いがある。
エイリアス
PowerShellのコマンドレットおよび関数には名前付け規則があって、どれも「動詞-名詞」といった構造になっている。最近は補完入力機能が充実しているのでこれでも構わないと言えば構わないのだが、インタラクティブに操作するには長すぎて煩雑だ。
そこで、PowerShellにはエイリアスと呼ばれる別名機能が用意されており、よく使われるものに関しては短縮名が用意されている。
例えば、Set-Locationにはcdというエイリアスが用意されているし、Clear-Hostにはclearというエイリアスが用意されている。Set-Locationに関しては、どの開発者もオリジナルの名前は使っていないだろう。Unixのシェルなどでcdが使われている影響もあり、ほとんどはこちらを利用していると思う。
ソースコードを見ていくと、cdもclearもエイリアスを設定する処理が行われていることがわかる。
エイリアスはSet-Aliasコマンドレットを使って設定可能で、pwsh起動後にエイリアスを追加することもできる。当然だが、pwshを終了すれば設定したエイリアスは消えてしまう。このあたりは関数と同じだ。
アプリケーション
PowerShellでは、PowerShell内部ではなく、OSにインストールされているコマンドのことを指す。
これまで紹介してきたコマンドレット、関数、エイリアスは、基本的にはPowerShellの内部で実装されている、ないしは、実行中のPowerShellのメモリ上に存在している。対してアプリケーションは、PowerShellの内部には存在していないコマンドになる。この点は大きな違いだ。
例えば、次の処理はアプリケーションを実行したものだ。calはコマンドレットではなくアプリケーションであり、実体は/usr/bin/calに存在している。PowerShellの外にあるものだ。
PowerShellではエイリアスにより別名で呼び出せるため、小文字のコマンドもそれがコマンドレットなのか関数なのかアプリケーションなのか、文字列を見ているだけではよくわからないかもしれない。ただ、WindowsとmacOS、Linuxのどの環境でも利用できるPowerShellを書けるようになりたいのであれば、アプリケーションとそれ以外については区別できるようにしておいた方がよい。
対象としているコマンドがコマンドレットなのか関数なのかエイリアスなのかアプリケーションなのかは、Get-Commandというコマンドレットで調べることができる。このあたりは今後紹介していく。
ソースコードを読んで理解する
マニュアルやドキュメントの説明も、時に何かがおかしいと感じることがある。そんなときは、ソースコードを追ってみるとよい。
おそらく設計の初期段階では、この概念とこの概念は明確に区別されていたけど、実装の関係でこうした方が速いから変わったんだろうな、などとわかってくることもある。また、実装がしやすいからこういう構造になって、結果としてマニュアルがあのような説明になったんだろう、と合点がいくこともある。
PowerShell Coreはソースコードが公開されているし、ソースコードはそれなりに読みやすいと思う。PowerShellの使い方を調べつつ、興味が及べばぜひソースコードにも手を伸ばしてもらうとよいだろう。gitコマンドでローカルにクローンを取っておくと便利だろう。