しばたテックブログ

気分で書いている技術ブログです。

PowerShellでmkdirしたディレクトリにcdする方法

クラスメソッドさんの

dev.classmethod.jp

が人気なので便乗してPowerShellだとどうすれば良いか軽く書いておきます。

本エントリの内容はWindows 10、PowerShell 5.1、PSReadline 1.2な環境で動作確認しています。

1. $$自動変数を使う

Bashでは$_が「ひとつ前に実行したコマンドラインの最後の引数」となっていますが、PowerShellで$_は「パイプラインで現在処理されているオブジェクト」を表す自動変数なので使えません。

PowerShellでは代わりに$$を使います。
$$は正確には「セッションが受け取った最後の行にある最後のトークン」なのですが、コマンド実行直後であれば「ひとつ前に実行したコマンドラインの最後の引数」と同じに使えます。

実行例はこんな感じです。

mkdir .\very\very\long-directory
cd $$

2. パイプラインでつなぐ

PowerShellではmkdir関数に成功すると作成されたディレクトリオブジェクト(System.IO.DirectoryInfo)を返します。
このため、この値をパイプラインでつなぎcd(Set-Location)に引き渡すことが可能です。

mkdir .\very\very\long-directory | cd

ただ、この方法でロケーションを移動した場合、プロンプトに表示されるロケーションが、

PS Microsoft.PowerShell.Core\FileSystem::C:\very\very\long-directory > 

の様に先頭にPSProvider(Microsoft.PowerShell.Core\FileSystem::の部分)が修飾されてしまう場合があり、見た目としては非常によろしくありません...

一応、

mkdir .\very\very\long-directory | % { $_.FullName } | cd

# or

mkdir .\very\very\long-directory | cvpa | cd

のように一旦%(ForEach-Object)や、cvpa(Convert-Path)をはさむことで回避はできるのですが、冗長で本末転倒です...

3. cd → Alt + . (PSReadline Windowsキーバインド)

PSReadlineを個別にインストールするか、標準でPSReadlineがインストール済みのWindows 10/Windows Server 2016環境でこの方法を使うことができます。

PSReadlineのデフォルトのキーバインドではAlt + .YankLastArgという機能で割り当てられており、「ひとつ前に実行したコマンドラインの最後の引数」を取得することができます。
このため、cdAlt + .の順に入力することで直近に入力したパスを補完することが可能です。

なお、キーバインドの割り当ては以下のコマンドで確認することができます。

Get-PSReadlineKeyHandler | ? { $_.Function -eq "YankLastArg" }

結果

Key   Function    Description
---   --------    -----------
Alt+. YankLastArg Copy the text of the last argument to the input

4. cd → ESC → . (PSReadline Emacsキーバインド)

PSReadlineではSet-PSReadlineOptionによりキーバインドを変更することができます。

Set-PSReadlineOption -EditMode Emacs

とすることでキーバインドをEmacs風にすることができ、この場合、cdESC.の順に入力すれば「ひとつ前に実行したコマンドラインの最後の引数」を取得することができます。

ちなみに、

Get-PSReadlineKeyHandler | ? { $_.Function -eq "YankLastArg" }

の結果は以下の様に変更されています。

Key      Function    Description
---      --------    -----------
Alt+.    YankLastArg Copy the text of the last argument to the input
Alt+=    YankLastArg Copy the text of the last argument to the input
Escape,. YankLastArg Copy the text of the last argument to the input
Escape,= YankLastArg Copy the text of the last argument to the input

5. ESC → k 0 cw cd (PSReadline viキーバインド)

PSReadlineはVer.1.2からvi風のキーバインドをサポートしています。

Set-PSReadlineOption -EditMode Vi

とするこでキーバインドをvi風にすることができます。
あとは元記事同様に、ESCk 0 cw cdで前回のコマンド呼び出し文字列置換を行う事ができます。

6. mkdir と cd を同時に実行する関数をあらかじめ定義しておく

独自の関数を作るのであれば好きなように作ってしまうのが良いと思います。

mkdir自体がNew-Itemコマンドレットをラップした関数なので、本格的な関数を作りたい人はmkdirの定義を確認してみると良いでしょう。
役に立つ情報を得ることができるはずです。

本エントリでは元記事に近い形の簡易な関数を紹介するにとどめておきます。

function mkdir-cd {
    mkdir $args[0] | cvpa | cd
}

※なお、PowerShellでは&&は予約語となっていますが、サポートされておらず使えません。

最後に

とりあえずこんな感じです。

BashやZshほどではないですがPowerShellでもいろいろな方法を選べますので是非試してみてください。