PowerShellがLinuxにポーティングされたようなので試してみた記録です
モノ
githubで公開されています
https://github.com/PowerShell/PowerShell/releases/latest
ソースも公開されているので実装の確認もできるようです
インストール
ドキュメントはこちら
https://github.com/PowerShell/PowerShell/blob/master/docs/installation/linux.md
CentOS7だとパッケージを落として
https://github.com/PowerShell/PowerShell/releases/latest
sudo yum install powershell-6.0.0_alpha.9-1.el7.centos.x86_64.rpm
だけですね
環境変数PSHOMEを設定します
export PSHOME='/opt/microsoft/powershell/6.0.0-alpha.9/'
実行
$ /opt/microsoft/powershell/6.0.0-alpha.9/powershell
ファイル名と時刻の一覧を出力してみます
bashだとこんな感じのモノ
$ ls -l | awk '{print $9","$6"/"$7"/"$8}'
,//
./,Feb/17/2016
../,Feb/17/2016
bin,Feb/17/2016
boot/,May/23/15:16
dev/,May/23/15:15
etc/,Aug/19/14:26
home/,Feb/29/19:05
lib,Feb/17/2016
lib64,Feb/17/2016
man/,Dec/1/2014
media/,Aug/12/2015
mnt/,Aug/12/2015
opt/,Aug/19/14:26
proc/,Feb/17/2016
root/,Apr/19/14:35
run/,Aug/19/14:26
sbin,Feb/17/2016
srv/,Aug/12/2015
sys/,Feb/17/2016
tmp/,Aug/22/10:22
usr/,Feb/17/2016
var/,Apr/19/14:39
Powershellではオブジェクトが使えるので
PS /> dir |foreach {Write-Host $_.name","$_.LastWriteTime}
bin , 2/17/16 4:58:42 PM
boot , 5/23/16 3:16:52 PM
dev , 5/23/16 3:15:40 PM
etc , 8/19/16 2:26:22 PM
home , 2/29/16 7:05:47 PM
lib , 2/17/16 4:58:42 PM
lib64 , 2/17/16 4:58:42 PM
man , 12/1/14 11:52:52 AM
media , 8/12/15 11:22:27 PM
mnt , 8/12/15 11:22:27 PM
opt , 8/19/16 2:26:22 PM
proc , 2/17/16 6:01:19 PM
root , 4/19/16 2:35:08 PM
run , 8/19/16 2:26:24 PM
sbin , 2/17/16 4:58:42 PM
srv , 8/12/15 11:22:27 PM
sys , 2/17/16 6:01:24 PM
tmp , 8/22/16 10:22:56 AM
usr , 2/17/16 4:58:43 PM
var , 4/19/16 2:39:38 PM
上記のdir
をls
にしても期待された動作はしません。
lsなどのOS側のコマンドをPowerShellのパイプに渡しても文字列として渡されるので出力解析はいままで通りのやり方が必要になります。
オブジェクトとして受け渡しを行いたいのであればPowerShellのコマンドや.NETオブジェクトを利用します。
シェルとしての利用
コマンド次第ですが非同期処理が実装されているのでインフラ屋的には並列処理がやりやすくなっています。
半面threadを意識するプログラミングが必要になるのでそこはpython/rubyとbashの中間くらいの位置づけでしょうか。
.NETとして
ざっと触ってみたところ文字エンコード周りは少し手を加える必要があるようです。
下記のコードはWindowsでは動きますがLinuxでは文字エンコードの関係でbodyの読み込み(ReadStringAsync)でエラーになります。
$http = New-Object System.Net.Http.HttpClient
$res = $http.GetAsync("https://www.google.com/")
$res.Result.Content.ReadAsStringAsync()
on windows
PS C:\> [System.Text.Encoding]::GetEncoding(932)
BodyName : iso-2022-jp
EncodingName : 日本語 (シフト JIS)
HeaderName : iso-2022-jp
WebName : shift_jis
WindowsCodePage : 932
IsBrowserDisplay : True
IsBrowserSave : True
IsMailNewsDisplay : True
IsMailNewsSave : True
IsSingleByte : False
EncoderFallback : System.Text.InternalEncoderBestFitFallback
DecoderFallback : System.Text.InternalDecoderBestFitFallback
IsReadOnly : True
CodePage : 932
on Linux
PS /> [System.Text.Encoding]::GetEncoding(932)
Exception calling "GetEncoding" with "1" argument(s): "No data is available for encoding 932. For information on
defining a custom encoding, see the documentation for the Encoding.RegisterProvider method."
At line:1 char:1
+ [System.Text.Encoding]::GetEncoding(932)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException
日本語まわりはこれからという感じなので内部で文字エンコード変換を行うオブジェクトは下記のようにバイトストリームで受け取ってから変換なり解析なりをするのが現状かと思います。α版なので正式版では対応されることをいのります。
$http = New-Object System.Net.Http.HttpClient
$res = $http.GetAsync("https://www.google.com/")
$res.Result.Content.ReadAsByteArrayAsync()
[System.Text.Encoding]::UTF8.GetString($res.Result)
おまじない(?)すればそのままいけるとのコメントを頂きましたので修正します。
[System.Text.Encoding]::RegisterProvider([System.Text.CodePagesEncodingProvider]::Instance)
$http = New-Object System.Net.Http.HttpClient
$res = $http.GetAsync("https://www.google.com/")
$res.Result.Content.ReadAsByteArrayAsync()
[System.Text.Encoding]::UTF8.GetString($res.Result)
Windowsではsjisがデフォルトだからそのまま動くようですね。
元がWindows用なのでどのプラットフォームでも動くようにするにはちょっと気を付けないといけないところでしょうか。
PS C:\> [System.Text.Encoding]::Default
BodyName : iso-2022-jp
EncodingName : 日本語 (シフト JIS)
HeaderName : iso-2022-jp
WebName : shift_jis
WindowsCodePage : 932
IsBrowserDisplay : True
IsBrowserSave : True
IsMailNewsDisplay : True
IsMailNewsSave : True
IsSingleByte : False
EncoderFallback : System.Text.InternalEncoderBestFitFallback
DecoderFallback : System.Text.InternalDecoderBestFitFallback
IsReadOnly : True
CodePage : 932