在程序参数中保留换行符和制表符 - Powershell

Keep newlines and tabs in argument to program - Powershell

我正在使用 Powershell 调用一个程序,该程序打印 Python 配置文件,其结构如下:

[distutils]
index-servers =
    some-pypi

[some-pypi]
repository: https://path/to/pypi

我想做的是将整个输出作为字符串传递给另一个命令。 不断发生的事情是,每当我将它传递给使用它的程序时,Powershell 最终会删除所有换行符和制表符特殊字符。 这会产生错误的输出。

下面是一些相关的命令及其输出。

> command to print config

打印所有内容时,换行符和制表符都完好无损。

> $settings = command to print config
> echo $settings

回显时,打印所有内容,换行符和制表符完好无损。

> consuming-program $settings

这无法解析,因为表达式解析将所有输出作为多个参数而不是单个参数提供给程序。

> consuming-program "$settings"

这会删除所有换行符和制表符。

> consuming-program "$(command to print config)"

同时取出所有的换行符。

我错过了什么?我怎样才能保留原始输出并将其作为单个参数输入到我的程序中,并且保留特殊字符??

发生这种情况是因为命令的输出被捕获为字符串的数组,而不是单个字符串。

例如,如果我们使用此命令作为基准:

C:\> dotnet

Usage: dotnet [options]
Usage: dotnet [path-to-application]

Options:
  -h|--help         Display help.
  --info            Display .NET information.
  --list-sdks       Display the installed SDKs.
  --list-runtimes   Display the installed runtimes.

path-to-application:
  The path to an application .dll file to execute.

然后在 PowerShell 中捕获输出,我们可以看到它是一个字符串数组 - 每行输出一个 - 而不是单个 multi-line 字符串:

PS> $x = dotnet
PS> $x.GetType().FullName
System.Object[]

当您将 $x 输出到控制台时,它会在单独的一行中显示数组中的每一项,因此它在视觉上看起来与控制台输出相同:

PS> $x

Usage: dotnet [options]
Usage: dotnet [path-to-application]

Options:
  -h|--help         Display help.
  --info            Display .NET information.
  --list-sdks       Display the installed SDKs.
  --list-runtimes   Display the installed runtimes.

path-to-application:
  The path to an application .dll file to execute.

但是 当您将它用作命令参数时,会发生其他事情 - 通过使用单个 space 连接数组中的项目,它被序列化为单个字符串作为分隔符:

 Usage: dotnet [options] Usage: dotnet [path-to-application]  Options:   -h|--help         Display help.   --info            Display .NET information.   --list-sdks       Display the installed SDKs.   --list-runtimes   Display the installed runtimes.  path-to-application:   The path to an application .dll file to execute.

这基本上就是 PowerShell 在某些情况下序列化数组的方式。例如,比较这两个命令的输出:

PS> @( "aaa", "bbb", "ccc" )
aaa
bbb
ccc

PS> write-host @( "aaa", "bbb", "ccc" )
aaa bbb ccc

正如@iRon 在评论中所建议的那样,一个解决方法是在您的命令中使用之前自行序列化字符串:

PS> $y = $x | Out-String
PS> $y

然后您可以使用 $y 作为保留原始格式的命令参数。