今年の初めに、PowerShell Coreはオープンソース(MIT)ライセンスの下で一般的に利用可能になりました。 PowerShellはほとんど新しいテクノロジーではありません。 2006年のWindows向けの最初のリリースから、PowerShellの作成者は、認識されている欠陥、特にコマンドの組み合わせから価値を引き出すためのテキスト操作の必要性を修正しながら、Unixシェルのパワーと柔軟性を組み込むことを目指しました。
5つのメジャーリリースの後、PowerShell Coreにより、同じ革新的なシェルとコマンド環境を、OSXやLinuxを含むすべての主要なオペレーティングシステムでネイティブに実行できるようになります。一部(読む:ほぼ全員 )は、太古の昔から(少なくともミレニアル世代によって定義されているように)強力なシェル環境を持っていたプラットフォームに自分自身を提供するために、このWindows生まれの侵入者の大胆さおよび/または冷静さをまだ嘲笑する可能性があります。この投稿では、PowerShellが経験豊富なユーザーにもメリットを提供できることを証明したいと思います。
プラットフォーム間の一貫性
スクリプトをある実行環境から別の実行環境に移植する場合は、機能するコマンドと構文のみを使用するようにする必要があります。たとえば、GNUシステムでは、次のように昨日の日付を取得します。
date --date="1 day ago"
BSDシステム(OS Xなど)では、BSD日付ユーティリティが次の構文を必要とするため、上記の構文は機能しません。
date -v -1d
PowerShellはパーミッシブライセンスの下でライセンスされ、すべてのプラットフォーム用に構築されているため、アプリケーションと一緒に出荷できます。したがって、スクリプトをターゲット環境で実行すると、スクリプトをテストした環境と同じコマンド実装を使用して、同じシェルでスクリプトが実行されます。
オブジェクトと構造化データ
* nixコマンドとユーティリティは、非構造化データを消費および操作する能力に依存しています。 sed
で何年も生きてきた人 grep
およびawk
この声明に悩まされることはないかもしれませんが、もっと良い方法があります。
PowerShellで昨日の日付の例をやり直してみましょう。現在の日付を取得するには、Get-Date
を実行します コマンドレット(「コマンドレット」と発音):
> Get-Date
2018年1月21日日曜日午後8時12分41秒
表示される出力は、実際にはテキストの文字列ではありません。むしろ、それは.NetCoreオブジェクトの文字列表現です。他のOOP環境の他のオブジェクトと同じように、そのオブジェクトにはタイプがあり、ほとんどの場合、呼び出すことができるメソッドがあります。
これを証明しましょう:
> $(Get-Date).GetType()。FullName
System.DateTime
$(...)
構文は、POSIXシェルに期待するとおりに動作します。括弧内のコマンドの評価結果は、式全体に置き換えられます。ただし、PowerShellでは、このような式では$は厳密にオプションです。そして、最も重要なのは、結果がテキストではなく.Netオブジェクトになることです。したがって、GetType()
を呼び出すことができます そのオブジェクトのメソッドを使用して、そのタイプオブジェクトを取得します(Class
と同様) Javaのオブジェクト)、およびFullName
タイプのフルネームを取得するためのプロパティ。
では、このオブジェクト指向性はどのようにあなたの生活を楽にしますか?
まず、任意のオブジェクトをGet-Member
にパイプできます コマンドレットを使用して、提供する必要のあるすべてのメソッドとプロパティを確認できます。
>(Get-Date)| Get-Member
PS / home / yevster / Documents / ArticlesInProgress> $(Get-Date)| Get-Member
TypeName:System.DateTime
Name MemberType ---------
メソッドを追加日時追加(タイムスパン値)
AddDays方法日時AddDays(二値)
AddHours方法日時AddHours(二値)
AddMillisecondsメソッド日時AddMilliseconds(ダブル値)
AddMinutes方法日時AddMinutes(ダブル値)
AddMonths方法日時AddMonths(int型ヶ月)
AddSeconds方法日時AddSeconds(ダブル値)
AddTicksメソッドの日時AddTicks(long value)
AddYearsメソッドdatetimeAddYears(int value)
CompareTo method int CompareTo(System.Object value)、int ...
DateTimeオブジェクトにAddDays
があることがすぐにわかります 昨日の日付をすばやく取得するために使用できるもの:
>(Get-Date).AddDays(-1)
2018年1月20日土曜日午後8時24分42秒
もう少しエキサイティングなことをするために、Yahooの天気予報サービス(APIトークンを必要としないため)に電話して、地元の天気予報を入手しましょう。
$ city ="Boston"
$ state ="MA"
$ url ="https://query.yahooapis.com/v1/public/yql?q=select%20*% 20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22 $ {city}%2C%20 $ {state}%22)&format =json&env =store%3A%2F%2Fdatatables.org%2Falltableswithkeys "
これで、昔ながらの方法でcurl $url
を実行することができます。 JSONの巨大なブロブを取得するには、または...
$weather=(Invoke-RestMethod $url)
$weather
のタイプを見ると (echo $weather.GetType().FullName
を実行する )、それがPSCustomObject
であることがわかります 。これは、JSONの構造を反映する動的オブジェクトです。
また、PowerShellは、タブ補完を使用してPowerShellをナビゲートするのに役立ちます。 $weather.
(必ず「。」を含めてください)そしてTabを押します。すべてのルートレベルのJSONキーが表示されます。 1つ入力し、その後に「.
」を入力します "、もう一度Tabキーを押すと、その子が表示されます(存在する場合)。
したがって、必要なデータに簡単に移動できます。
<前>>エコー$ weather.query.results.channel.atmosphere.pressure>エコー$ weather.query.results.channel.wind.chill
41
また、JSONまたはCSVが非構造化データとして存在する(または外部コマンドによって返される)場合は、それをConvertFrom-Json
にパイプするだけです。 またはConvertFrom-CSV
それぞれコマンドレットを使用すると、データをきれいなオブジェクトに保存できます。
コンピューティングと自動化
シェルは2つの目的で使用します。 1つは、コンピューティング、個々のコマンドの実行、およびそれらの出力への手動応答です。もう1つは自動化で、複数のコマンドを実行し、それらの出力にプログラムで応答するスクリプトを記述します。
私たちのほとんどが見落とすことを学んだ問題は、これらの2つの目的がシェルに異なる矛盾する要件を課すことです。コンピューティングでは、シェルが簡潔である必要があります。ユーザーが逃げることができるキーストロークが少ないほど、良い結果が得られます。ユーザーが入力した内容が他の人間にかろうじて判読できるかどうかは重要ではありません。一方、スクリプトはコードです。読みやすさと保守性が重要です。そしてここで、POSIXユーティリティはしばしば失敗します。一部のコマンドは簡潔な構文と読み取り可能な構文の両方を提供しますが(例:-f
および--force
)一部のパラメータについては、コマンド名自体が読みやすさではなく、簡潔さの側面で誤りを犯しています。
PowerShellには、ファウストのトレードオフを排除するためのいくつかのメカニズムが含まれています。
まず、タブ補完により、引数名の入力が不要になります。たとえば、Get-Random -Mi
と入力します 、Tabキーを押すと、PowerShellが引数を完了します:Get-Random -Minimum
。しかし、本当に簡潔になりたいのであれば、Tabキーを押す必要さえありません。たとえば、PowerShellは理解します
Get-Random -Mi 1 -Ma 10
Mi
およびMa
それぞれに固有の補完があります。
すべてのPowerShellコマンドレット名が動詞-名詞構造を持っていることに気付いたかもしれません。これはスクリプトの読みやすさを向上させるのに役立ちますが、おそらくGet-
と入力し続けたくないでしょう。 コマンドラインで何度も繰り返します。だからしないでください!動詞なしで名詞を入力すると、PowerShellはGet-
を検索します その名詞を使ったコマンド。
注意:PowerShellは大文字と小文字を区別しませんが、PowerShellコマンドを使用する場合は、名詞の最初の文字を大文字にすることをお勧めします。たとえば、date
と入力します システムのdate
を呼び出します 効用。 Date
と入力します PowerShellのGet-Date
を呼び出します コマンドレット。
それでも不十分な場合は、PowerShellに単純な名前を作成するためのエイリアスがあります。たとえば、alias -name cd
と入力した場合 、cd
が見つかります PowerShellのコマンド自体は、Set-Location
のエイリアスです。 コマンド。
したがって、確認するために、強力なタブ補完、エイリアス、名詞補完を取得して、コマンド名を短く、自動的に、一貫性のあるものに保ちます。 スクリプト名の豊富で読みやすい構文を楽しみながら、パラメータ名の切り捨て。
それで...友達?
PowerShellにはいくつかの利点があります。まだ説明していない機能やコマンドレットが他にもあります(Where-Objectまたはそのエイリアス?
を確認してください)。 grep
を作成したい場合 泣く)。そして、ねえ、あなたが本当にホームシックを感じているなら、PowerShellはあなたのためにあなたの古いネイティブユーティリティを喜んで起動します。ただし、PowerShellのオブジェクト指向コマンドレットの世界に慣れるのに十分な時間をとってください。そうすれば、帰り道を忘れることを選択するかもしれません。