2017-01-27 54 views
1

私は、次の2つのスクリプトがあります:inner.ps1exitコマンドは、呼び出し元スクリプトmain.ps1からの出口がないので、私は二回を打つのPowershell:再帰スクリプト呼び出し

### main.ps1 
. .\inner.ps1 $args[0] $myInvocation.MyCommand.Definition 
echo "second call" 
Write-Host -NoNewLine "Press any key to continue..." 
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") 

### inner.ps1 
if($($args[0]) -ne "secondRun") { 
    echo "first" 
    echo $($args[1]) 
    & $($args[1]) "secondRun" 
    exit  
} 

を2番目のコールはコードです。

発信者からも退席できますか?
適切な再帰を取得するにはどうすればよいですか?
私はすべてを入れたい/ inner.ps1における再帰の負担の大半とmain.ps1に追加避ける意味し、できるだけきれいにmain.ps1を保つような行:

でもドットソーシングと
if($($args[0]) -ne "secondRun") {exit;} 

答えて

2

.あなたの現在の設定にあなたが. .\inner.ps1呼び出し後に終了する必要があるかどうかをチェックmain.ps1の条件いくつかを必要とするので)、スクリプトは、exitにその呼び出し側に指示することはできません。 再帰は全く必要である理由ヘルパースクリプトinner.ps1ドットソース化されているので、呼び出し側の環境を変更することができ、main.ps1ことを考えると

、人は不思議。
しかし、この回答の残りの部分は質問の前提を受け入れています。

OP自身がa solution that encapsulates the recursive-invocation details inside inner.ps1を思い付いたが、問題は、制御情報を送信するために成功ストリーム(通常の出力ストリーム)を使用していることである - $TRUEまたは$FALSEする - (その情報をチェックすることif文を意味しますif (. .\inner.ps1) ...の標準出力を消費します。したがって、を抑制します。 [1]すなわち

main.ps1が全く出力を生成しないことが発生した場合のアプローチのみ動作し、または発信者が気にしない何が起こるかmain.ps1出力

### inner.ps1 

if(-not $__inner_already_recursed) { 

    'inner: reinvoking main...' 
    $__inner_already_recursed=$true # set flag to indicate that recursion has happened 
    . $myInvocation.ScriptName  # re-invoke main.ps1 

    exit 0 # Signal need to continue execution with $LASTEXITCODE 0 

} else { 

    'inner: not reinvoking...' 
    exit 1 # Signal that this is already the 2nd invocation. 

} 

と:

溶液は、(PowerShellが自動変数$LASTEXITCODEに反映)終了コードに制御フローをベースにあるOPの状態として

### main.ps1 

'main: entering' 

# Call the helper script that performs the recursive invocation. 
. .\inner.ps1 
if ($LASTEXITCODE -eq 1) { exit } # 1 means previously already reinvoked -> exit 

# We only get here once, in the recursive invocation. 
'main: should only get here once' 

、再帰呼び出し状態をinner.ps1に維持するために使用される補助変数は、あらかじめ存在してはいけません(少なくとも真実の値ではない)ので、その名前-012そのリスクを最小限に抑えるためにが選ばれました。


[1] Write-Host呼び出しは、彼らがコンソールに直接印刷するので、影響を受けませんが、その出力は、キャプチャさもなく、パイプラインを介して送信することもできません。

+1

nice weekend friendly user :) –

-1

このアプローチは、発信者の側で非常に軽いようだ(、あなたはPSV5 +にできたが、それは一般的に無分別、ここで有用ではありません。追加の努力で)。

### inner.ps1 
if(-not $recurseScript) { 
    write-host "first" 
    write-host $myInvocation.ScriptName 
    $recurseScript=$TRUE 
    & $myInvocation.ScriptName 
    return $TRUE 
} 

$recurseScript=$FALSE 
return $FALSE 

main.ps1を再帰的にするために、今私はラインif(. .\inner.ps1) {exit}必要があります両方に定義され、$TRUEmain.ps1を実行する前に存在してはならない。もちろん、

### main.ps1 
if(. .\inner.ps1) {exit} 

Write-Host "second"; 
Write-Host -NoNewLine "Press any key to continue..."; 
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown"); 

変数$recurseScriptを。

+0

'main.ps1'が定期的な成功ストリーム出力を生成しない場合や、その出力に興味がない場合にのみ、あなたのアプローチはオプションであるという大きな免責事項を追加する必要があります。それが作成するすべての(成功ストリーム)出力は、 'if'ステートメントによって消費されます。出力を見る唯一の理由は 'Write-Host'を使っているからですが、それはコンソールにまっすぐに向かい、キャプチャもリダイレクトもできません。 – mklement0

関連する問題