#背景
WSLでLinux環境が手軽に使えるようになったので、PowerShellとLinuxのコマンドラインを行き来する機会が多くなった。
そうなると、PowerShellで作業している時についcurl http://example.com
のように入力してしまい勝ちだが、PowerShellは標準でcurlやwgetにInvoke-WebRequestコマンドレットをエイリアスとして割り当てているため、期待どおりの出力じゃなくて微妙な気分になる。
個人的にはInvoke-WebRequestが使いたいならそう書くよ!と思ったので、curlとwgetについては標準のエイリアスを上書きしたいと思った。(ちなみにInvoke-WebRequestにはiwrという標準エイリアスがあるので尚更…)
設定系は次にやる時まで内容を覚えていない事が多いので、メモとして記録してみる。
#Windows用のcurl, wgetをインストール
Chocolateyを使っているので、cinst
でさくっとインストール完p了。
PS C:\>cinst curl wget -y
個別に入れたい場合は、それぞれ以下から入手可能。
curl - Download
GNU Wget 1.19.2 for Windows
#エイリアスの上書きのテスト
Set-Aliasコマンドレットで上書きしてみる。
Chocolateyでは%ChocolateyInstall%\bin
フォルダにShimを作ってくれるので、そこを参照する。
(個別にインストールした場合はインストール先のフルパスを指定する)
PS C:\>sal curl (Join-Path $env:ChocolateyInstall "bin\curl.exe")
※sal
はSet-Aliasのエイリアス
が、これで実行してみたら以下のエラー
PS C:\> sal curl (Join-Path $env:ChocolateyInstall "bin\curl.exe")
sal : AllScope オプションをエイリアス 'curl' から削除できません。
発生場所 行:1 文字:1
+ sal curl (Join-Path $env:ChocolateyInstall "bin\curl.exe")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (curl:String) [Set-Alias], SessionStateUnauthorizedAccessException
+ FullyQualifiedErrorId : AliasAllScopeOptionCannotBeRemoved,Microsoft.PowerShell.Commands.SetAliasCommand
どうやら既定のエイリアスがAllScopeで定義されているため、Localスコープのエイリアスとして上書きする事ができない模様。
AllScope
をオプションにつけて実行してみる。
PS C:\> sal curl (Join-Path $env:ChocolateyInstall "bin\curl.exe") -O AllScope
PS C:\> gal curl
CommandType Name Version Source
----------- ---- ------- ------
Alias curl -> curl.exe
※gal
はGet-Aliasのエイリアス
できた。
#$Profileの作成
以上の手順だけだとセッションごとにやり直す必要があるので、プロファイルで設定を行うようにする。
Bashでいうところの*~/.bash_profileとか~/.bashrc*に相当するのがPowerShellだと$Profileで参照できるファイル。
※注意:ユーザーやホスト(ISE等)ごとに指定方法が異なるので、詳しくはこちらを参照。
notepad $profile
とかで適当にエディタで開いて以下の内容で作成。
#Alias
$aliases = @{
curl = Join-Path $env:ChocolateyInstall "bin\curl.exe";
wget = Join-Path $env:ChocolateyInstall "bin\wget.exe";
}
$aliases.GetEnumerator() | % {if (Test-Path $_.Value) {sal $_.Key $_.Value -O AllScope}}
後で同様の追加がし易いようにハッシュテーブルに「エイリアス名=コマンドのファイルパス」形式で定義してみた。
コマンドがあれば追加するエイリアスをセットする。
ファイルを上書き保存し、PowerShellの開き直してgal
で確認→OK。
#おまけ
当初、
$aliaese | % {...}
でやってみたらうまく値が取れなくて悩んだが、PowerShellのハッシュテーブルは明示的にGetEnumerator()
を付けないと列挙できないらしい。(知らなかった…)
参考:PowerShellのHashtableがコレクション扱いされない話 - しばたテックブログ
C#脳だとハマるポイントかも。
#追記(2017-11-19)
curl, wgetコマンドがパスの通った場所にインストールされているのであれば、
#Alias
del alias:curl
del alias:wget
として単純にエイリアスを削除するだけでも良かった。
こっちの方がシンプル。
ただパスでの解決に頼っちゃうと、cygwin
とかで同名のコマンドがインストールされたら意図せず呼ばれるプログラムが変わる可能性がある。(パスの指定順に気をつければ良いとは言え)
curlやwgetみたいに同じ挙動のプログラムならあんまり問題ないんだけど、ちょっと気持ち悪い。
それが嫌なら、どっちにしろ同名のエイリアスを作る処理を足さないといけないので、あんまり変わらないかな。
#追記(2017-12-20)
curlについて、tarと共に Insider Build 17063 から標準搭載されるそうです。
Insider Buildはまだ試してませんが、PowerShellの標準aliasも無くなるかな?
Tar and Curl Come to Windows! | Virtualization Blog
#追記(2018-05-04)
April 2018 Updateを適用後に確認したところ、Invoke-WebRequest
へのエイリアスとしてcurl
が残っていました。(wget
も同様)
コマンドプロンプトも使う人は注意が必要ですね。