运行 来自另一个 shell 的 PowerShell with Tee

Running PowerShell from another shell with Tee

我想学习从另一种 shell 或语言执行 PowerShell 命令,例如Pythonos.system()。我想要实现的是:

  1. 执行 PowerShell 命令
  2. 将输出发送到控制台和文件
  3. Return 命令退出代码

我认为这给出了我想要实现的目标,假设使用 cmd.exe 作为调用者环境:

powershell -NoProfile -command "& { cat foo.txt  | Tee-Object ps-log.txt; exit $LASTEXITCODE }"
echo %errorlevel%

这里有些问题。首先,我不能在命令中使用引号,例如:

powershell -NoProfile -command "& { cat `"foo bar.txt`"  | Tee-Object ps-log.txt; exit $LASTEXITCODE }"

cat 参数似乎未加引号传递,因此 cat 查找 'bar.txt' 参数。

我认为 $LASTEXITCODE 很快就会展开,那是在 cat 执行之前。

& 使用起来不方便,因为它不接受包含参数的单个命令行字符串。 & 的替代方法是 iex,但我无法在 cmd.exe 中使用它。事实上:

powershell  -NoProfile -command  {iex cat  foo.txt}

returns:

iex cat foo.txt

来自 cmd.exe,使用以下内容(-c-Command 的缩写):

C:\>powershell -NoProfile -c "Get-Content \"foo bar.txt\" | Tee-Object ps-log.txt; exit -not $?"
  • 没有理由在传递给 -Command 的字符串中使用 & { ... } - 只需使用 ... 即可。

  • 转义 嵌入 " 个字符。作为 \"(PowerShell(核心)7+ 也接受 "")。

    • 或者,因为需要 points out, you can use '...' (single-quoting) inside the "..." string passed to -Command / -c, assuming that no string interpolation
  • 因为只有PowerShell-native命令参与了命令(在Windows上,cat只是[的别名=38=] 适用,它是一个 布尔值 ,指示最近执行的管道中的命令是否发出任何错误。

    • -not否定这个值意味着$true转换为$false$false转换为$true,这些值在外部被转换为 整数 $false 映射到 0$true 映射到 1

Powershell 支持单引号,这让我在这种情况下省了很多次。它的好处是:它们明确且易于阅读。但请注意,变量扩展在单引号字符串中不起作用。

powershell -NoProfile -command "cat 'foo bar.txt' | tee ps-log.txt"

除此之外,看看 mklement0 的回答中的有用建议。