如何将 JSON 内容回显到 exe 文件,然后将输出保存到文件?

How to echo JSON content to an exe file and then save the output to a file?

我正在使用 git bash 中的脚本,它对期望和生成 protobuf 的 HTTP 端点执行很少的 curl 调用。

curl 输出通过管道传输到自定义 proto2json.exe 文件,最后将结果保存到 JSON 文件:

#!/bin/bash

SCRIPT_DIR=$(dirname [=11=])
JSON2PROTO="$SCRIPT_DIR/json2proto.exe"
PROTO2JSON="$SCRIPT_DIR/proto2json.exe"

echo '{"key1":"value1","version":3}' | $JSON2PROTO -v 3 > request.dat

curl --insecure --data-binary @request.dat --output - https://localhost/protobuf | $PROTO2JSON -v 3 > response.json

该脚本运行良好,现在我正在尝试将其移植到 Powershell:

$SCRIPT_DIR = Split-Path -parent $PSCommandPath
$JSON2PROTO = "$SCRIPT_DIR/json2proto.exe"
$PROTO2JSON = "$SCRIPT_DIR/proto2json.exe"

@{
        key1        = value1;
        version     = 3;
} | ConvertTo-Json | &$JSON2PROTO -v 3 > request.dat

不幸的是,当我比较“git bash”和 Powershell 中生成的二进制文件时,我发现后者的文件额外输入了零字节。

GitHub issue #1908 与我的问题有关吗?

看起来你最终是在追求这个:

$SCRIPT_DIR = Split-Path -parent $PSCommandPath
$JSON2PROTO = "$SCRIPT_DIR/json2proto.exe"
$PROTO2JSON = "$SCRIPT_DIR/proto2json.exe"

# Make sure that the output from your $JSON2PROTO executable is correctly decoded
# as UTF-8.
# You may want to restore the original encoding later.
[Console]::OutputEncoding = [System.Text.Utf8Encoding]::new()

# Capture the output lines from calling the $JSON2PROTO executable.
# Note: PowerShell captures a *single* output line as-is, and
#       *multiple* ones *as an array*.
[array] $output = 
  @{
        key1        = value1;
        version     = 3;
  } | ConvertTo-Json | & $JSON2PROTO -v 3

# Filter out empty lines to extract the one line of interest.
[string] $singleOutputLineOfInterest = $output -ne ''

# Write a BOM-less UTF-8 file with the given text as-is,
# without appending a newline.
[System.IO.File]::WriteAllText(
  "$PWD/request.dat",
  $singleOutputLineOfInterest
)

至于你试过的

  • 在 PowerShell 中,> 是带有 -Encoding 参数的 Out-File cmdlet, whose default output character encoding in Windows PowerShell is "Unicode" (UTF-16LE) - which is what you saw - and, in PowerShell (Core) 7+, BOM-less UTF8. To control the character encoding, call Out-File or, for text input, Set-Content 的有效别名。

    • 请注意,您可能还必须确保外部程序的输出首先被正确解码,这是基于存储在 [=16= 中的编码发生的] - 有关详细信息,请参阅

    • 请注意,从 v7.2.4 开始,您无法在 PowerShell 中避免这些解码 + re-encoding 步骤,因为 PowerShell 管道目前不能作为管道原始字节 ,如 中所讨论,它也链接到您提到的 GitHub 问题。

    • 最后,请注意 Out-FileSet-Content 默认情况下都附加一个 尾部,platform-native 换行符 输出文件。虽然 -NoNewLine 抑制了它,但它也抑制了 多个输入对象之间的换行符,因此您可能必须使用 -join 运算符手动将输入与换行符连接起来所需的格式,例如(1, 2) -join "`n" | Set-Content -NoNewLine out.txt

  • 如果在 Windows PowerShell 中,您想要创建没有 BOM的 UTF-8 文件,您可以' t 使用 file-writing cmdlet 并且必须直接使用 .NET APIs(PowerShell(核心)7+,相比之下,生成 BOM-less UTF-8 文件 默认 ,始终如一)。 .NET API 默认创建 BOM-less 个 UTF-8 文件;例如:

    • [System.IO.File]::WriteAllLines() 将数组的元素作为行写入输出文件,每行 以 platform-native 换行符终止 ,即 Windows 上的 CRLF (0xD 0xA) 和 Unix-like 平台上的 LF (0xA)。

    • [System.IO.File]::WriteAllText() 写入一个 单个 (可能 multi-line)字符串 as-is 到输出文件。

    • 重要:始终将 完整路径 传递给 file-related .NET API,因为 PowerShell 的当前位置(目录)通常不同于 .NET 的。