Linuxで快適にPowershellを使うためのコツ

## 概要
PowershellをLinuxやMacにインストールすると、Windows版のPowershellと設定や挙動が違っています。この投稿は、Windowsである程度、Powershellを使っていた人が、戸惑わずにLinuxやMacでPowershellを使用できるように、キーバインドなどを調整するためのものです。

Macを使用している方は、Linuxと書かれている部分をMacに読み替えれば、ほぼ同じ内容で対応できます。Powershellのインストールや基本的な操作に関しては、他の記事を参照してください。

## 機能面について
Windows版のPowershellとLinux版のPowershellでは、管理系のコマンドがWindows版にしか用意されていないので、Windows版とできる作業の内容が変わってきます。

基本的に、Linux版のPowershellからはOSの設定は行えません。Linuxには無い機能に関してのコマンドレットはオミットされています。また、サービスの制御についても、WindowsとLinuxで仕組みが違うため、Powershellでの標準機能で制御はできません。```Out-GridView``` のようなGUIを表示するコマンドも、Linux版では標準で使用できません。

Linux版の用途としては、WindowsとLinuxでModuleの互換性が高いので、Moduleをインストールして使用するようなコマンドレットを使用することが多くなります。

## 操作面での違い
もう一つ、PowershellのWindows版とLinux版での大きな違いはキーバインドになります。このキーバインドの違いで、Windows版のPowersehellに慣れた人がLinux版のPowerahellを操作すると違和感を感じることがあります。

実はPowershellには複数のキーバインドが用意されています。キーバインドは、```Get-PSReadLineOption```というコマンドレットの出力にある **EditMode** の項目からキーバインドを確認できます。Windows版で実行すると、以下のような出力になります。

```Powershell
PS C:\Users\Main> Get-PSReadLineOption

EditMode                               : Windows
AddToHistoryHandler                    : System.Func`2[System.String,System.Object]
HistoryNoDuplicates                    : True
.
.
.
```

Powershell のキーバインドには、**Vi**、**Emacs**、**Windows** の三種類あります。それぞれのキーバインドの詳細は Get-PSReadLineKeyHandler から確認できます。WindowsでPowershellを使い慣れている人は、キーバインドをWindowsに設定すると、Windowsで使用していた時に近いキーバインドでLinuxのPowershellを操作できます。

WindowsのPowershellで ```Set-PSReadLineOption -EditMode``` と入力したあとに **Ctrl+Space** (メニュー補完) を押すと、以下のように入力できる値の選択肢が出力され、矢印キーで選択することができるようになります。

```Powershell
PS C:\Users\Main> Set-PSReadLineOption -EditMode Emacs
Emacs    Vi       Windows
```

Windowsで使用するPowershellとLinuxで使用するPowershellで **PSReadLine** のオプションに **EditMode** に同じ設定をしておくと、近い感覚で操作することができます。

## 補完について
Powershellのコマンドレットは数も多く、一つ一つ覚えていたら非常に大変です。そのため、補完による入力が前提になります。PowershellをLinuxで使用する場合、この補完の機能を意図したとおりに動かせることが快適に使用するために必要になってきます。

Powershellで ```Get-PSReadLineKeyHandler``` のコマンドレットを実行すると、現在設定されているキーバインドを確認できます。Windowsで何も設定していない状態で実行したときの補完に関する設定は、以下のようになっています。

```Powershell
・
・
・
Completion functions
====================

Key           Function            Description
---           --------            -----------
Ctrl+@        MenuComplete        Complete the input if there is a single completion, otherwise complete the input by s
                                  electing from a menu of possible completions.
Ctrl+Spacebar MenuComplete        Complete the input if there is a single completion, otherwise complete the input by s
                                  electing from a menu of possible completions.
Tab           TabCompleteNext     Complete the input using the next completion
Shift+Tab     TabCompletePrevious Complete the input using the previous completion
・
・
・
```

設定されているキーバインドの中で、**Completion functions** 以下が補完の設定になります。補完には以下の種類の機能が設定できます。

|設定値|挙動|
|---|---|
|MenuComplete | メニューからの補完。候補から矢印キーで値を選択できる。|
|Complete | 補完の候補を全部表示する。|
|PossibleCompletions | 使用できる補完の候補を表示する。|
|TabCompleteNext | 補完の候補を一つ表示する。|
|TabCompletePrevious | 表示した補完の候補を逆順に表示する。|

このうち、Windowsのキーバインドで標準で設定されているのは、**MenuComplete** と **TabCompleteNext** と **TabCompletePrevious** の三つです。**MenuComplete** で **Ctrl+Space** と **Ctrl+@** の二つにキーバインドが設定されているのは、使用するキーボードによっては、**Ctrl+Space** で入力言語を切り替えることがあるからです。

Powershellを使いこなすうえで、**MenuComplete** の機能は重要です。どのようなキーバインドを使用するにせよ、この機能が使えるように設定しておきましょう。

## キーバインドの設定
キーバインドの種類は、以下のコマンドで設定することができます。コマンドを実行すると、変更が即時適用されます。

```Powershell
Set-PSReadLineOption -EditMode <キーバインドの種類>
Emacs    Vi       Windows 
```

使用するキーボードの種類によってキーバインドがうまく動かないことがあったりします。そのような場合、こちらにの以下のコマンドを実行して、個別にキーバインドを設定します。

```Powershell
Set-PSReadLineKeyHandler -Function <対応する機能> -Key <キーバインド>
```

```Get-PSReadLineKeyHandler``` の出力で **Function** の項目にある機能を **key** に入力したキーバインドに割り振ります。入力する値は、```Get-PSReadLineKeyHandler``` の出力内容を確認してください。```Get-PSReadLineKeyHandler``` のコマンドに、```-Unbound``` のオプションをつけることで、割り振られていない機能の一覧を確認することができます。

## 設定内容の保存
Powershellの起動時に ```$Profile``` のパスに保存されているスクリプトが実行されます。スクリプトのExecutionPolicy(実行実行制御のポリシー)をスクリプトが実行できる権限に変更して、```$Profile```に設定した際のコマンドを列挙しておきます。そうすることで、実行時にコマンドが実行され、設定が反映されます。