いままでもずっと手間だなと感じてはいたのですが、「ディレクトリを作成してすぐにそのディレクトリに移動するということ」。これまでは非IT系のジャンルにいたので、CLIなどの作業はあまりありませんでしたが、最近はその職から離れ、開発的なところにいるので、CLIを頻繁に使用するようになりました。そうなると、ディレクトリの作成・移動がとても頻繁にあるし、かなり面倒に感じて来ました。そこで、もう少し簡単に出来ないかと感じ、調査・改善をすることにしました。
大した内容ではないのでメモです。
bash
での改善
具体的には以下の2つのコマンドを短縮したいということになります。
初期状態
$ mkdir hoge $ cd hoge
ワンライナーに変更するとなると以下のようになります。
&&
は前段(左側のコマンド)が成功したら後段(右側のコマンド)を実行するというものになります。
1行にはなりましたが、タイプ数がほぼかわりません。
ワンライナー化 その1
$ mkdir hoge && cd hoge
さらにもう少し短縮するとなると以下のようになります。
ワンライナー化 その2
$ mkdir hoge && cd $_
$_
は、直前のコマンドで最後に使った引数を参照するため、hogeに移動できます。これでディレクトリが長くなればかなりのタイプ数を減らすことができるようになりました。サブディレクトリの直接作成を考えるのであれば、mkdirに-p
オプションをつけてもいいですね。そうすると途中作成していないディレクトリがあっても自動で生成してくれます。
例えば、mkdir -p foo/bar/baz
のように使うと、foo
、bar
、baz
のディレクトリがすべて存在しない場合に、一度に全てを作成します。また、既に指定したディレクトリが存在する場合もエラーを出さずにそのまま実行ができます。
ちなみに-p
はparentsの略になります。
ワンライナー化 その3
$ mkdir -p ./fuga/hoge && cd $_
これで結構楽になりました😊
bashの関数として定義してみる
先ほどのワンライナーの内容をbash関数として定義すればもっと短く実装も可能です。
.bashrcに以下の関数を追記します。
mkdirとcdの組み合わせをする関数mkcd
mkcd() { mkdir -p "$1" && cd "$1" }
.bashrc
ファイルを編集して追加してもいいのですが、以下のコマンドを実行すれば、即追加できます。以降は.bashrc
が読み込まれれば使用することができます。
$ echo 'mkcd() { mkdir -p "$1" && cd "$1"; }' >> ~/.bashrc $ source ~/.bashrc
以降は以下のように実行できます。
$ mkcd hoge
これでかなり短くなりました🤩
WindowsのPowerShell
での改善
すべての環境がbash
であれば特に問題ないのですが、Windowsの場合はPowerShell
でも同様のことが発生します。このときに関しても改善ができないかを同様に考えました。
対象とするのは以下です。bash
と見た目はかわりません。
PS> mkdir hoge PS> cd hoge
純粋にPowerShell
を使用すると以下のようになります🤨
PS> New-Item -ItemType Directory -Path "hoge" -Force; Set-Location "hoge"
長い、長すぎる
PowerShell
はコマンドにエイリアスがあり、New-Item -ItemType Directory
のエイリアスはmkdir
、Set-Location
のエイリアスはcd
となります。
そのため、以下でよいのですが…以下で実行すると、New-Item -ItemType Directory
で適用している-Force
の機能はなくなります。また、bash
で&&
となっていた部分は;
に置き換えられていますが、これはbash
の&&
と違い、成功失敗にかかわらず次のコマンドを実行してしまいます。これはかなり難問。
PS> mkdir "hoge"; cd "hoge"
もし、同じ意味実行し、キータイプを短縮するのであれば、PowerShell
のコマンドやオプションの短縮表記を使用して以下のように実行することになります。結構マシですが、何言ってるかわからないコマンドになったような…
【短縮表記】 - New-Item → ni - ItemType → -i - Path → -p - Set-Location → sl
PS> ni -i Directory -p "hoge" -Force; sl "hoge"
これを記憶する自信はない😢
PowerShell
のプロファイルに関数として定義する
では、bash関数
のように関数化できないかを考えます。PowerShell
では.bashrc
のような設定ファイルとして$PROFILE
が存在します。(パスはそれぞれですが、$PROFILE
とすることで参照としては一意になります)
$PROFILEの実際のファイルはこちらになります。
PS> echo $PROFILE C:\Users\【ユーザ名】\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
ファイルがないこともあるので以下のようにファイルを作成します。存在していなければ$PROFILE
を作成するというものです。
$PROFILEのファイル作成
PS> if (!(Test-Path -Path $PROFILE)) { New-Item -ItemType File -Path $PROFILE -Force }
$PROFILEへ関数の追加と設定の反映
# $PROFILEへ追加 $ Add-Content -Path $PROFILE -Value @' function mkcd { param($path) New-Item -ItemType Directory -Path $path -Force; Set-Location $path } '@ # なんらかのスクリプト実行ポリシーの変更が必要(今回は*RemoteSigned*としている) # 現在のセッションのみでスクリプト実行ポリシーの変更をしています。 PS> Set-ExecutionPolicy RemoteSigned -Scope Process -Force # 設定の反映 PS> . $PROFILE # 現在のセッションでも必要があればスクリプト実行ポリシーは戻してください。
これで以下のように実行できます。
PS> mkcd hoge
この手法ではPowerShell
のスクリプト実行ポリシーを操作しているので、あまりいい手段ではない感じですが、仕方ないのでしょうか?ポリシーはデフォルトから変えたくない場合はどうするのか、まだ分かっていません。
これほどの手間なら、もはや以下でもいいのかも🥲
PS> mkdir hoge; cd hoge
おわりに
今回は日々のCLI操作で煩わしいと感じるディレクトリの作成直後のそのディレクトリへの移動について、より簡単に実行する方法を模索しました。bash
ではワンライナー化や関数定義によって、少しでも手間が減りコーディングや作業効率が向上しましたが。PowerShell
では実行ポリシーの部分が解決していないので今ひとつとなってしまいましたが、ポリシーさえ解決すれば…みなさんってスクリプト実行ポリシーって変更してるんですか?🤔
ということで、何かあったらまた追記したいと思います。