Powershell 的管道兼容性 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
ColinZeb

Powershell 的管道兼容性

  •  
  •   ColinZeb Jul 29, 2020 4166 views
    This topic created in 2098 days ago, the information mentioned may be changed or developed.

    在 windows 上试用 gzip 遇到个管道的坑。

    windows 上是没有 gzip 命令的。

    首先安装 scoop install gzip

    压缩命令一般这么写 cat script.ps1|gzip >script.gz

    这个写法在 bash zsh 和 cmd 都能正常工作,但是 pwsh 不行,甚至 powershell 5 也不行。

    我知道 ps 管道可以传 PS-Object,但不会不会兼容文件流吧,目前还没找到说这个问题的,先在这分享一下继续寻找 解决方案。

    9 replies    2022-03-05 19:45:19 +08:00
    Tumblr
        1
    Tumblr  
       Jul 29, 2020
    ♂ 在 PowerShell 中,cat 是 Get-Content 的 alias,获取出来的是按行分割的数组;
    管道传递的时候,是一个元素一个元素地传递,这样写肯定不行了。
    ColinZeb
        2
    ColinZeb  
    OP
       Jul 29, 2020
    @Tumblr 不是 cat 的问题,换成 wsl cat 也一样的
    ghostwwg/td>
        3
    ghostwwg  
       Jul 29, 2020
    木有问题啊。。。
    ghostwwg
        4
    ghostwwg  
       Jul 29, 2020
    indows PowerShell
    版权所有 (C) Microsoft Corporation 。保留所有权利。

    尝试新的跨平台 PowerShell https://aka.ms/pscore6

    PS C:\Users\ghost> cat .\testpage|gzip > aaa.gz
    PS C:\Users\ghost> ls .\aaa.gz


    目录: C:\Users\ghost


    Mode LastWriteTime Length Name
    ---- ------------- ------ ----
    -a---- 2020/7/29 14:09 56 aaa.gz


    PS C:\Users\ghost>
    geelaw
        5
    geelaw  
       Jul 29, 2020   1
    楼主的遇到的问题是多重问题,第一步 cat 就已经错了,因为它会以文本读取文件,而不是复制二进制流。
    第二步管道传入 gzip 也错误,因为经过 PowerShell 的外部程序管道都会经过文本的转换。
    第三步保存到文件也错误,因为这个操作也会按照文本解读,还会进行编码转换。

    正确解法是使用 Start-Process 来重定向,但是这只能解决输入输出都是文件的简单情况。

    那么 PowerShell 使用二进制管道的正解是什么呢?这里臭不要脸地推荐我写的 module Use-RawPipeline,专门解决 PowerShell 二进制管道交互问题,且在 Windows 上以性能最佳的方式实现。

    GitHub 链接: https://github.com/GeeLaw/PowerShellThingies/tree/master/modules/Use-RawPipeline
    博客: https://geelaw.blog/entries/powershell-use-rawpipeline/

    @ghostwwg #4 有文件出现不代表文件内容是对的。
    ColinZeb
        6
    ColinZeb  
    OP
       Jul 29, 2020
    @ghostwwg 打开文件试试。
    @geelaw bash 环境里的 cat 支持文本文件和二进制文件重定向到管道,我以为 pwsh 会兼容
    LokiSharp
        7
    LokiSharp  
       Jul 29, 2020
    @ColinZeb #6 pwsh 传的是对象,不是文本。。。
    geelaw
        8
    geelaw  
       Jul 29, 2020 via iPhone   1
    @ColinZeb #6 bash 不支持“文本重定向”,它对文本没有概念,管道是二进制流。至于 cat,那是一个外部程序,它也不懂“文本”的概念,只是负责把多个文件粘在一起。举个例子,当你 cat 多个用 UTF 编码的文本文件时,结果不会得到统一的编码,也不会删除多余的 BOM 。

    PowerShell 没有特别想要兼容其他 shell 的用法,而且管道传输对象本来就和大多数 shell 不兼容。
    hez2010
        9
    hez2010  
       Mar 5, 2022
    这是一个古老的问题: https://github.com/PowerShell/PowerShell/issues/1908 ,PowerShell 的 > 会把东西转换成文本导致原数据被破坏,只不过因为为了兼容性一直没有进行这个破坏性更改。
    另外 PowerShell 的 cat 也是默认转换成字符串数组,要用 Get-Content -AsByteStream xxx 或者 cat -AsByteStream xxx 才能获取到源数据。

    不过下一个版本 PowerShell 7.3 应该会给出解决方案。
    About     Help     Advertise     Blog     API     FAQ     Solana     5669 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 70ms UTC 09:00 PVG 17:00 LAX 02:00 JFK 05:00
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86