Powershell 在 cmdlet 所在位置退出

Powershell exits on where cmdlet

我正在编写一个脚本,应该 运行 两个 python apps 然后循环解决方案文件,使用 pyjson 扩展并在每次满足任何条件时重新启动这些 apps。我在获取文件名的时候碰壁了。在这一点上(第 6 行),第二个 ps window 只是立即关闭,即使两个不同的命令应该暂停它,之后还有两个,如果在线有 where 部分,它就会退出6、无所事事。

$bot = start python .\source\run.py -WorkingDirectory .\bot -WindowStyle Hidden -PassThru # start bot app and save info about it
$web = start python .\source\run.py -WorkingDirectory .\web -WindowStyle Hidden -PassThru # start web app and save info about it
$cycle = start powershell { # start new ps window which will check if any file was changed 
    cmd /c pause # does nothing ???
    Read-Host # does nothing ???
    $fs = dir .\ -recurse | where { $_.extension -in ".py",".json" };
    cmd /c pause # does nothing ???
    Read-Host # does nothing ???
} -PassThru
echo Stop? # indicate script is ready to stop
Read-Host # wait for input before stopping
Stop-Process -Id $bot.Id # stop bot app
Stop-Process -Id $web.Id # stop web app
Stop-Process -Id $cycle.Id # stop second ps window

您对 Windows PowerShell CLI 的调用,powershell.exe隐式 使用 -Command
(-c)参数
.

为了在
-Command 参数中识别命令字符串中嵌入的 " 字符,您必须将它们转义为 \"
(原文如此) - 否则,它们在初始 command-line 解析期间有效地 被删除 - 请参阅 的底部部分以获取背景信息.
或者,您可以使用嵌入式 '...' 引号,这不需要转义。

  • 由于您忽略了执行此转义,该命令变得语法无效,导致新的 PowerShell window auto-closing 几乎瞬间(在打印错误)。
  • 作为一般故障排除提示,在命令参数前加上 -NoExit,这会保持 PowerShell 会话并因此 window 打开,这样您就可以看到发生了什么错误。

此外,在使用 script block literal ({ ... }) is syntactically convenient, it can be be conceptually confusing, given that the positionally implied -ArgumentList (-Args) parameter of the Start-Process (start) 时,您传递的脚本块是 [string[]] 类型的,因此总是将参数转换为 字符串。 因此,请考虑改用(逐字)here string

将它们放在一起(请注意,为了简单起见,我正在使用 PowerShell 的 built-in pause 函数,它只是一个 Read-Host 包装器,包含以下代码:$null = Read-Host 'Press Enter to continue...'):

$bot = start python .\source\run.py -WorkingDirectory .\bot -WindowStyle Hidden -PassThru # start bot app and save info about it
$web = start python .\source\run.py -WorkingDirectory .\web -WindowStyle Hidden -PassThru # start web app and save info about it

# Note how " is escaped as \" 
# Alternatively, use ' (while equivalent here, it isn't always)
$cycle = start -PassThru powershell @'
    pause
    dir .\ -recurse | where { $_.extension -in \".py\", \".json\" }
    pause
'@

Read-Host Stop? # wait for input before stopping
Stop-Process -Id $bot.Id, $web.Id, $cycle.Id

另请注意:

  • String Stop? 直接传递给 Read-Host(它隐式绑定到 -Prompt 参数),使 Read-Host 本身打印细绳;但是,请注意 : 总是附加到指定的字符串。

  • 一个 single Stop-Process 调用就足够了,因为它的 -Id 参数接受一个 array 个 PID(进程 ID)。