rcmdnk's blog

Windows PowerShellクックブック

Windowsで使われているシェルのPowerShellがオープンソース化し、 さらにMacやLinuxへもインストールして使える様になりました。

PowerShell for every system!

GitHubでPowerShellのソースが公開されています。

PowerShell is open sourced and is available on Linux

同時に、ここからMac用やLinux用のインストールイメージもダウンロードできるようになっています。

Package installation instructions: https://github.com/PowerShell/PowerShell/blob/master/docs/installation/linux.md

ここにあるとおり、Ubuntuなら、apt-get、CentOSならyumで 必要パッケージを入れてからPowerShellのパッケージファイルを使ってインストール出来るようになっています。

Ubuntu 16.04なら

$ sudo apt-get install libunwind8 libicu55
$ wget https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.9/powershell_6.0.0-alpha.9-1ubuntu1.16.04.1_amd64.deb
$ sudo dpkg -i powershell_6.0.0-alpha.9-1ubuntu1.16.04.1_amd64.deb

Mac (OS X)では10.11用のpkgファイルが用意されていて、 Releaseページ から powershell-6.0.0-alpha.9.pkg をダウンロードしてきてインストールを行います。

$ wget https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.9/powershell-6.0.0-alpha.9.pkg
$ sudo installer -pkg powershell-6.0.0-alpha.9.pkg -target /

でインストール完了です。

Linuxではインストール先は

/opt/microsoft/powershell/6.0.0-alpha.9/

Macでは

/usr/local/microsoft/powershell/6.0.0-alpha.9/

になっています。

これらのディレクトリはPowerShellを立ち上げると$PSHOMEという値に設定されています。

PS /usr/local> Write-Host $PSHOME
/usr/local/microsoft/powershell/6.0.0-alpha.9

MacでHomebrewを使っていれば /usr/localが既に存在していると思いますが、 もし存在していない場合、El Capitanから導入されたSIPによって 弾かれる可能性があるので その場合は下に従って一度SIPを切って/usr/localディレクトリを用意する必要があります。

ちなみに、Homebrewで探してみると

$ brew search powershell
Caskroom/cask/powershell

と、Caskがありそうなんですが、caskで探すと、

$ brew cask search powershell
No Cask found for "powershell".

無く、実際Caskファイルは探してもありません。

ちょっと謎ですが、多分PowerShellのインストール用CaskなりFormulaは そのうち公式の中に出来ると思います。

Macで使ってみる

取り敢えずMacに入れてみましたが、 /usr/local/microsoft/powershell/6.0.0-alpha.9/に本体がインストールされると同時に、 /usr/local/bin/powershell/usr/local/microsoft/powershell/6.0.0-alpha.9/powershellへのリンクが貼られていました。

OS Xでは/usr/local/bin下にできますが、Linuxだと /usr/bin/powershellと、/usr/bin/下にシンボリックリンクが出来ます。

また、$HOME/.config/PowerShell$HOME/.local/share/powershellというディレクトリが出来ていました。

Homebrewを使っている場合には通常 /usr/local/bin/にPATHを通していると思うので、 インストール後、単にコマンドを実行すると

$ powershell
PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS /usr/local>

の様にMacの中でPowerShellが立ち上がります!

まず、これを見ても分かる通り、パスの区切りがバックスラッシュ(\)ではなく 通常のスラッシュ(/)で表現されています。

WindowsのPowerShellでもパスの区切りは\/のどちらでも 使えますが、表示する時は\です。

Macなどでも両方使えますが、表示する時はUnix標準の/で表される様です。

で、実際にPowerShellコマンドが使えます。

PS /usr/local> Get-ChildItem


    Directory: /usr/local


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----          X/XX/XX  XX:XX PM                bin
d-----          X/XX/XX  XX:XX PM                Caskroom
d-----          X/XX/XX  XX:XX PM                Cellar
d-----          X/XX/XX  XX:XX AM                djcelery
d-----          X/XX/XX  XX:XX PM                etc
d-----          X/XX/XX  XX:XX AM                Frameworks
d-----          X/XX/XX  XX:XX AM                gems
d-----          X/XX/XX  XX:XX AM                include
d-----          X/XX/XX  XX:XX AM                lib
d-----          X/XX/XX  XX:XX AM                Library
d-r---          X/XX/XX  XX:XX AM                microsoft
d-----          X/XX/XX  XX:XX PM                opt
d-----          X/XX/XX  XX:XX AM                share
d-----          X/XX/XX  XX:XX PM                texlive
d-----          X/XX/XX  XX:XX AM                var
------          X/XX/XX  XX:XX PM           3161 CODEOFCONDUCT.md
------          X/XX/XX  XX:XX AM           1241 LICENSE.txt
------          X/XX/XX  XX:XX AM           5451 README.md


PS /usr/local>

PowerShell特有のパイプ機能(アウトプットをオブジェクトとして渡す機能)も使えます。

PS /usr/local> Get-ChildItem|Select-Object -property Length,Name -first 3

Length Name
------ ----
       bin
       Caskroom
       Cellar


PS /usr/local>

PowerShell的システム管理入門:第2回 PowerShellの基礎 (1/3) - @IT

Windows PowerShell でのパイプ処理とパイプライン

PowerShellはコマンドプロンプトのコマンドと比べると大分 Bash等と同じ様なイメージで使えますが、 基本的なコマンド名が違うものになっています。

Learning PowerShell

ですが、WindowsのPowerShellの場合、例えばlsなんかは PowerShellのGet-ChildItemというコマンドのエイリアスになっていて、 Bashのコマンド名は一通りPowerShellの似た機能のエイリアスになっています。

一方、MacやLinuxにインストールされたPowerShellの中ではこの様なエイリアスは 作られてない状態で、ls等を使うと元々の/bin/lsにあるコマンドが呼ばれる様です。

PS /usr/local> ls
CODEOFCONDUCT.md  README.md   lib
Caskroom    bin     microsoft
Cellar      djcelery    opt
Frameworks    etc     share
LICENSE.txt   gems      texlive
Library     include     var
PS /usr/local>

こんな感じでBashなどで使うlsと同じ出力になります。 引数もls -l等、Bash等で使うlsのものが使え結果も それに従って出ます。

Known Issues for PowerShell on Linux: https://github.com/PowerShell/PowerShell/blob/master/docs/KNOWNISSUES.md

他のコマンドやシェルスクリプトも普通に使えます。

ただ、GNU screen等を立ち上げて(PowerShellからでも起動は可能)、 その中のPowerShellでPowerShellのもので無いコマンド(lsなり自作スクリプトなり)を使うと 結果出力直後に固まります。

PowerShellでは出力を色々特殊な扱いしてる面もあるので その辺GNU screenやtmuxと言った ターミナルマルチプレクサとはちょっと相性が悪いのかもしれません。

アンインストール

アンインストールに関する記述が見つけられませんでしたが、 基本的には/opt/microsoft(Linux)または/usr/local/micfosoftを 削除して、/usr/bin/powershell、または/usr/local/bin/powershellの シンボリックリンクを削除すれば良いだけだと思います。

設定ファイルも消したければ、 ~/.config/PowerShell~/.local/share/powershellも。

Macのデフォルトシェルにしてみる

PowerShellもBashやZsh同様シェルの一つなので当然デフォルトシェルに指定することも出来ます。

Macでデフォルトシェル(ログインシェル)を変更する方法については下を参考に。

これで環境設定などから変更してあげて、ターミナル.app等を立ち上げると

Last login: Fri Aug 19 XX:XX:XX on ttys015
PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS /Users/user>

みたいな感じでいきなりPowerShellが立ち上がります。

これで常にPowerShellで作業が出来ます!

PowerShellスクリプトをBash等から使う

PowerShellをインストールしたので当然PowerShellスクリプトも使えるわけですが、 通常、PowerShellの中では.ps1という拡張子が付いたファイルを PowerShellスクリプトだと解釈して中身を実行します。

Bashなどでは拡張子は関係ないのでこのままだと使えません。 使うには他のシェルやコマンド同様、Shebangを書いてあげれば良いだけ。

test.ps1
1
2
3
#!/usr/bin/env powershell

Write-Host "Hello world!"

これでBashからでも

$ ./test.ps1
Hello world!

と実行できます。 このファイルはPowerShellからでももちろん実行できます。

PowerShellではファイルのパーミッションが関係ない (実行ファイルなのか読み書き専用ファイルなのか)のですが、 Bashから実行する時には実行ファイルにするために

$ chmod 755 ./test.ps1

等パーミッションを変更しておく必要があります。

また、シェルスクリプトは拡張子は.shでなくても何であっても構わないわけですが、 PowerShellスクリプトは.ps1でないと しばらくフリーズした後に、

$ ./test.sh
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'System.Diagnostics.StackTrace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. A device attached to the system is not functioning.
...

みたいなエラーが出ました。 .ps1という拡張子を使わないとダメなようです。

Known Issues for PowerShell on Linux: https://github.com/PowerShell/PowerShell/blob/master/docs/KNOWNISSUES.md

初期設定ファイル

上で、インストール時に $HOME/.config/PowerShellというディレクトリが出来ていたと書きましたが、 この中にprofile.ps1というファイルを作ると 起動時に読み込んでくれます。

システム全体で設定を決めたい時は$PSHOME/profile.ps1というファイルを 作り設定を書き込めばOK。

差し当たり、PATHがデフォルトでは/usr/bin:/bin:/usr/sbin:/sbinという状態になってたので これに付け足す設定を書きました。

PowerShellではPATHは$ENV:PATHで設定します。

/Users/user/.config/PowerShell/profile.ps1
1
$ENV:PATH = "$HOME/usr/local/bin:$HOME/usr/bin:/usr/local/bin:$ENV:PATH"

こんな感じ。

ここでちょっと注意が必要なのは、 WindowsのPowerShellでは各パスの区切るとしてセミコロン(;)を使いますが、 MacやLinuxではBash等と同様コロン(:)を使う様になっています。

Bashのコマンドラインからpowershellを立ち上げると Bashで設定していた$PATHがPowerShellの$ENV:PATHに設定されていました。

上に書いたディレクトリ間区切りの表現等も含めた共通化のため、 Windows板とMac/Linux板では微妙な違いもあるみたいです。

まとめ

Windowsでのコマンドプロンプトはあまり使い勝手が良いとは言えないものでしたが、 PowerShellは使い勝手も良いし、 BashやZshに比べるとパイプでの出力が渡しがオブジェクト形式だったり かなり高機能な面がありしたが Windowsでしか使えない物なのであまり一般的には使われてなかった感があります。

ただ、今回MacやLinuxでも使えるようになったため、 シェルの一つの選択肢としてBashやZshと並んで選べる様になりました。(多分)

ソースもオープンソース化したことで、ユーザーフィードバックも 素早く取り込める様になるでしょうし、 新たなシェルの選択肢として普通にありだと思います。

今のところ上に書いたscreen内でのPowerShell以外のコマンドを打つとフリーズする、 というのが大きな問題で完全移行をすることはありませんが、 その辺も何か分かったらフィードバックしようと思います。 (もしくは単にIssue立てるか。多分誰かがすぐ出すと思いますが。)

直接これと関係ないかもしれませんがtmuxやscreen関係のIssueは既に結構あって、 以下の様なものもありました。

Fix console when TERM is not xterm · Issue #546 · PowerShell/PowerShell

PowerShellのテストがMacでも簡単に出来る、と言うのは結構便利なので それだけでも今回のリリースは嬉しい所です。

先日のWindows 10 Anniversary Updateで Windows内で動くBashが正式に実装されましたが、 このBash自体はWindowsシステムの操作は出来ないので、 今回のPowerShellのオープンソース化及びMac/Linux用にも使える様になったこと の方がよっぽど衝撃的だと思います。

いずれにしろ時代の流れなのか大分アグレッシブに攻めてる感があります。

Sponsored Links
Sponsored Links

« 120年分のオリンピック100m走金メダリストを一斉に走らせたら PowerShell on Bash on Ubuntu on Windows »

}