4

我正在尝试更新 Windows 服务器上的主机文件,并尝试使用 powershell 中的 heredoc 进行更新。

我无法弄清楚为什么我的结果在每个主机条目中的每个字符之间都有额外的空格。

我正在从 Linux 移植一些脚本。

PS C:\Users\Administrator> cat C:\Users\Administrator\AppData\Local\Temp\etchosts.ps1
@"
127.0.0.1 src.example.com
127.0.0.2 builds.example.com
127.0.0.3 ti.example.com
127.0.0.4 jira.example.com
"@ >>C:\Windows\System32\drivers\etc\hosts



PS C:\Users\Administrator> powershell C:\Users\Administrator\AppData\Local\Temp\etchosts.ps1
PS C:\Users\Administrator> cat C:\Windows\System32\drivers\etc\hosts
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#       127.0.0.1       localhost
#       ::1             localhost
 1 2 7 . 0 . 0 . 1   s r c . e x a m p l e . c o m

 1 2 7 . 0 . 0 . 2   b u i l d s . e x a m p l e . c o m

 1 2 7 . 0 . 0 . 3   t i . e x a m p l e . c o m

 1 2 7 . 0 . 0 . 4   j i r a . e x a m p l e . c o m

我希望所有字符之间没有空格。如果有“Windows”方法可以做到这一点,我将不胜感激任何输入/建议。

4

2 回答 2

6

here-string只是 PowerShell 字符串文字的一种特殊形式,与 PowerShell 和 .NET ( ) 中的所有字符串一样,它们System.String内存编码始终为UTF-16。

  • 顺便说一句:要正确地将字符串文字读入内存,必须正确编码封闭的脚本文件;最好的选择是带有 BOM的 UTF-8 - 请参阅此答案

但是,重要的是如何将(内存中的)字符串写入文件

>> file实际上与 相同| Out-File -Append file,并且在Windows PowerShell中 Out-File 默认为 UTF16-LE 编码 ("Unicode"),其中每个字符(通常)用2 个字节编码。看起来是空格的东西实际上是每个 ASCII 范围字符编码的第二个字节中的NUL( ) 字节。0x0

  • 顺便说一句:在 PowerShell Core中,无 BOM 的 UTF-8 是 - 更明智的 - 默认值;由于 UTF-8 向后兼容 ASCII 范围内的字符,因此您的代码在 PowerShell Core 中可以正常工作。

相比之下,C:\Windows\System32\drivers\etc\hosts是 ASCII 编码的(每个字符 1 个字节)。

要匹配该编码,请使用Add-Content代替>>

@"
127.0.0.1 src.example.com
127.0.0.2 builds.example.com
127.0.0.3 ti.example.com
127.0.0.4 jira.example.com
"@ | Add-Content C:\Windows\System32\drivers\etc\hosts

与 不同Out-File -AppendAdd-Content 匹配文件预先存在的内容的编码(如果没有,则默认为 Windows PowerShell 中的活动 ANSI 代码页的编码(“默认”),如Set-Content);在没有 BOM 的情况下,如在这种情况下,假定 ANSI 编码,但由于 ANSI 代码页是 ASCII 的超集,因此使用与 ASCII 实际上相同的仅 ASCII 范围输入字符。


也可以看看:

于 2019-08-16T23:04:12.433 回答
1

我永远不会使用“out-file -append”或“>>”。它不检查当前编码是什么。这是 powershell 5 的一个可怕特性。现在你有一个混合了 ascii 和 unicode 的文件。空格实际上是空值。在这种情况下,我更喜欢添加内容。添加内容将首先检查 BOM。

于 2019-08-17T00:41:41.853 回答