Powershell は、選択したコマンドレットをデフォルトの出力ストリームに結び付け、コマンドの終了後にそれを解放しないようで、将来のコマンドに予期しない方法で影響を与えます。これを行う方法に一貫性がないため、スクリプトを作成するときに明示的に出力を指示しないと、予測可能な出力を生成できません。
この奇妙な現象は、コマンドを別の行に配置したり、異なるオブジェクト生成コマンドレットを混在させたりした場合に発生します。コマンドを別の行で対話的に実行しても発生しません。また、コマンド ラインで自動的に作成されたオブジェクトでは発生しません。 、コマンド ラインで自動的に作成されないオブジェクトを混在させない限り。
コマンドラインのインタラクティブな例を示しますが、これらのコマンドをスクリプトに入れ、各コマンドを別々の行に配置してからスクリプトを実行すると発生します。
PS /home/dennis> get-date|select dayofweek ; get-date
DayOfWeek
---------
Monday
Monday
PS /home/dennis> "string1"|select length ; "string2"
Length
------
7
string2
そして、楽しみのために、これをチェックしてください:
S /home/dennis> "string0" ;"string1"|select length ; get-host ;"string2" ;get-date; 567 ; get-host
string0
Length
------
7
1
string2
1
567
1
PS /home/dennis> cat test.ps1
"string0"
"string1"|select length
get-host
"string2"
get-date
567
(1..5)
get-host
PS /home/dennis> ./test.ps1
string0
Length
------
7
1
string2
1
567
1
2
3
4
5
1
...
これは、同じタイプではないオブジェクトにも影響し、実際には、select ステートメントにプロパティを持たないオブジェクトにも影響します。遅延はオプションではなく、out-host または write-host を使用して出力を明示的に強制すると、powershell 出力デバイスに直接書き込まれるため、パイプラインでオブジェクトを生成するために使用されるスクリプトを作成する必要がなくなります。また、変数を台無しにします。観察:
PS /home/dennis> $d = get-date | select dayofweek ; $e = get-date ; $d ; $e
DayOfWeek
---------
Monday
Monday
PS /home/dennis> $d
DayOfWeek
---------
Monday
PS /home/dennis> $e
Monday, August 5, 2019 12:33:47 PM
考えている人にとっては、これは単なる表示の問題であり、スクリプトを正しく表示するように記述できます。繰り返しますが、これにより、スクリプトは他のスクリプトで再利用できるツールとして役に立たなくなります。スクリプト内のパイプラインが独立したインタラクティブ シェルのコマンドにどのように影響するかを観察します。
PS /home/dennis> cat test.ps1
"string0"
"string1"|select length
get-host
"string2"
get-date
567
get-host
PS /home/dennis> ./test.ps1|% {$_}
string0
Length
------
7
1
string2
1
567
1
PS /home/dennis> ./test.ps1|% {write-host $_}
string0
@{Length=7}
System.Management.Automation.Internal.Host.InternalHost
string2
8/5/19 12:50:54 PM
567
System.Management.Automation.Internal.Host.InternalHost
PS /home/dennis> ./test.ps1|% {$_|out-host}
string0
Length
------
7
Name : ConsoleHost
Version : 6.2.2
InstanceId : 4e46c643-1a9d-4c55-9151-b311f287a9cb
UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture : en-US
CurrentUICulture : en-US
PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled : True
IsRunspacePushed : False
Runspace : System.Management.Automation.Runspaces.LocalRunspace
string2
Monday, August 5, 2019 1:20:24 PM
567
Name : ConsoleHost
Version : 6.2.2
InstanceId : 4e46c643-1a9d-4c55-9151-b311f287a9cb
UI : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture : en-US
CurrentUICulture : en-US
PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled : True
IsRunspacePushed : False
Runspace : System.Management.Automation.Runspaces.LocalRunspace
どのシェル スクリプトでも、前のコマンドとは独立してコマンドが実行されることを期待しています。WhatTheFortran は、この動作の背後にあるロジックですか? この予測不可能性を回避するための公式の推奨事項は何ですか?