V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
AndyAO
V2EX  ›  问与答

难题: git 的 Unicode 输出在 PowerShell 中可以显示,却不能保存到变量,是怎么回事?

  •  1
     
  •   AndyAO · 107 天前 · 348 次点击
    这是一个创建于 107 天前的主题,其中的信息可能已经有所发展或是发生改变。

    为了解决 git 的 Unicode 显示问题,已经更改了能够想到的配置和环境变量(具体见文末)。

    直接显示是没有问题的,但是如果将流传入管道中或保存到变量里面,编码就会出错。

    # 错误流,没有捕捉直接显示则不会有任何问题;标准输出流被传入管道之后,就会产生错误,将“①”显示为“鈶?”
    PS>git rev-parse '①' | Out-String
    fatal: ambiguous argument '①': unknown revision or path not in the working tree.
    Use '--' to separate paths from revisions, like this:
    'git <command> [<revision>...] -- [<file>...]'
    鈶?
    

    还有个奇怪的现象:如果用的是 vscode 里面的 PowerShell Integrated Console,则一切正常。

    到底是哪里出了问题?


    配置和环境变量

    [gui]
    	encoding = utf-8
    	recentrepo = D:/GitRepository/PowerShell
    [i18n "commit"]
    	encoding = utf-8
    [i18n]
    	logoutputencoding = utf-8
    

    LESSCHARSET = "utf-8"

    3 条回复    2021-09-09 08:37:31 +08:00
    AndyAO
        1
    AndyAO  
    OP
       107 天前
    补充版本信息

    * * *

    PS>$PSVersionTable

    Name Value
    ---- -----
    PSVersion 7.1.3
    PSEdition Core
    GitCommitId 7.1.3
    OS Microsoft Windows 10.0.18363
    Platform Win32NT
    PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
    PSRemotingProtocolVersion 2.3
    SerializationVersion 1.1.0.1
    WSManStackVersion 3.0

    PS>git --version
    git version 2.29.2.windows.2
    AndyAO
        2
    AndyAO  
    OP
       106 天前
    原因是如果直接使用 git 命令,那么输出的内容其实并不经过 PowerShell,而是直接传递到终端。

    但如果使用任何其他的 PowerShell 机制,那么则会处理。

    PowerShell 会对输入的内容的编码进行判断,如果判断失败了就会出现那种情况。

    可以通过更改 Console 类的属性来指定输入输出编码。

    [Console]::OutputEncoding = [Console]::InputEncoding = $OutputEncoding = [Text.UTF8Encoding]::new($false)

    具体效果如下 ↓


    PS>git rev-parse '①' | Out-String
    fatal: ambiguous argument '①': unknown revision or path not in the working tree.
    Use '--' to separate paths from revisions, like this:
    'git <command> [<revision>...] -- [<file>...]'



    不得不说当前 PowerShell 在字符串编码方面做得还不够好。

    * * *

    上述内容来自 reddit

    https://www.reddit.com/r/PowerShell/comments/paauvs/problem_the_unicode_output_of_git_can_be/ha3gnma?utm_source=share&utm_medium=web2x&context=3
    geelaw
        3
    geelaw  
       90 天前   ❤️ 1
    因为当命令行是原生命令时,PowerShell 直接让原生命令写入它自己的 stdin/stdout/stderr 。
    当原生命令是表达式的一部分时,例如赋值给变量,PowerShell 会开启一系列糟糕的操作,见 https://geelaw.blog/entries/powershell-use-rawpipeline/
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1336 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 23:42 · PVG 07:42 · LAX 15:42 · JFK 18:42
    ♥ Do have faith in what you're doing.