Даже с дот-источников (.
), скрипт не может поручить своему вызывающих к exit
, поэтому в текущей настройке вам необходимо некоторых условного в main.ps1
, который проверяет необходимость выхода после . .\inner.ps1
вызова.
Учитывая, что вспомогательный скрипт inner.ps1
в настоящее время точка-источников и, следовательно, может изменять окружающую среду вызывающего абонента, main.ps1
, один спрашивает, почему рекурсии необходимо в целом.
Остальная часть этого ответа, однако, согласна с предпосылкой вопроса.
ОП сам придумал a solution that encapsulates the recursive-invocation details inside inner.ps1
, но проблема заключается в том, что с помощью потока успеха (регулярный выходной поток) для передачи управляющей информации - $TRUE
или $FALSE
- означает, что if
заявление, которое проверяет, что информация (if (. .\inner.ps1) ...
) потребляет стандартный выпуск из main1.ps1
и поэтому подавляет. [1]
Другими словами: подход работает только если main.ps1
происходит не производить никакого вывода вообще, или вызывающий бывает не волнует, что main.ps1
выходы.
решения основывать поток управления на кодах выхода (которые PowerShell отражает в автоматической переменной $LASTEXITCODE
):
### 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.
}
и:
### 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
, не должна существовать заранее (или, по крайней мере, не иметь правдивого значения), поэтому ее имя - $__inner_already_recursed
- был выбран для минимизации этого риска.
[1] Write-Host
вызовов не влияет, потому что они печатают непосредственно на консоль, но их выход не может быть ни захваченный, ни послал по трубопроводу.
(с дополнительным усилием, вы можете в PSv5 +, но это как правило, непродуманными и не полезно здесь.)
Столько усилий. Хороший дружеский пользователь в выходные дни :) –