Powershell 将数据传输到外部控制台应用程序

2024-01-02

我有一个可以接受标准输入的控制台应用程序。它缓冲数据直到执行命令,此时它会执行所有数据,并将输出发送到标准输出。

目前,我正在从 Powershell 运行该应用程序,将命令通过管道传输到其中,然后解析输出。传入的数据相对较小;然而,该应用程序被调用了大约 1000 次。每次执行时,它都必须加载并创建网络连接。我想知道将所有命令管道化到控制台应用程序的单个实例中是否会更有效。

我尝试过将所有为控制台生成标准输入的 Powershell 脚本添加到一个函数中,然后将该函数通过管道传输到控制台应用程序。一开始这似乎有效,但您最终意识到它正在缓冲 Powershell 中的所有数据,直到函数完成,然后将其发送到控制台的 StdIn。您可以看到这一点,因为我有一整套 Write-Host 语句一闪而过,只有这样您才能看到输出。

e.g.

Function Run-Command1
{
    Write-Host "Run-Command1"
    "GET nethost xxxx COLS id,name"
    "EXEC"
}

Function Run-Command2
{
    Write-Host "Run-Command2"
    "GET nethost yyyy COLS id,name"
    "GET users yyyy COLS id,name"
    "EXEC"
}

...

Function Run-CommandX 
{
...
}

以前,我会将其用作:

Run-Command1 | netapp.exe -connect QQQQ -U user -P password
Run-Command2 | netapp.exe -connect QQQQ -U user -P password
...
Run-CommandX | netapp.exe -connect QQQQ -U user -P password

但现在我想做的是:

Function Run-Commands
{
    Run-Command1
    Run-Command2
    ...
    Run-CommandX
}

Run-Commands |
netapp.exe -connect QQQQ -U user -P password

理想情况下,我希望将 Powershell 管道行为扩展到外部应用程序。这可能吗?


我希望将 Powershell 管道行为扩展到外部应用程序。
我有一大堆 Write-Host 语句一闪而过,只有这样你才能看到输出。

Tip of the hat to marsze https://stackoverflow.com/users/2060966/marsze.

  • PowerShell [Core] v6+ performs no buffering at all, and sends (stringified) output as it is being produced by a command to an external program, in the same manner that output is streamed between PowerShell commands.[1]

  • PowerShell 的旧版(版本高达 5.1),Windows PowerShell, 缓冲区在那它收集命令的所有输出first在将其字符串化发送到外部程序之前。

    • marsze 的有用答案 https://stackoverflow.com/a/64664003/45375显示了基于直接使用 .NET API 的解决方法。

然而,我认为即使Windows PowerShell的行为不是这里的问题:你的Run-Commands函数执行得非常快 - 考虑到它调用的函数仅输出字符串文字 - 然后将生成的行数组一次性发送到netapp.exe- 进一步的处理,包括何时产生输出,取决于netapp.exe. In PowerShell [核心] v6+,在 PowerShell 端缓冲的情况下,个人Run-Commmand<n>函数的输出将被发送到netapp.exe稍微早一点,但我不认为这会产生影响。

结果是unless netapp.exe提供了一种调整其输入和输出缓冲的方法,您将无法控制其输入处理和输出产生的时间.


PowerShell 如何将对象发送到外部程序(本机实用程序)通过管道:

  • It sends a stringified representation of each object:
    • in PowerShell [核心] v6+: 当对象变得可用时.
    • in Windows PowerShell:收集内存中的所有输出对象后first.

In other words: on the PowerShell side, from v6 onward, there is no buffering.[1]

  • However, receiving external programs typically do buffer the stdin (standard input) data they receive via the pipeline[2].

    • 同样,外部程序通常do缓冲他们的stdout(标准输出)流(但 PowerShell 在传递输出之前不执行额外的缓冲,例如传递到终端(控制台))。

    • PowerShell 无法控制此行为;外部程序本身提供调整缓冲的选项,或者在有限的情况下Linux,您可以通过以下方式调用外部程序stdbuf utility https://linux.die.net/man/1/stdbuf.


可选阅读:如何使用 PowerShell字符串化管道传输到外部程序时的对象:

  • 从 v7.1 开始,PowerShell 只知道text与外部程序通信时;也就是发送的数据to此类程序被转换为文本,并输出from这样的程序是解释为文本 - 尽管底层系统 IPC 功能很简单byte导管。

  • PowerShell 使用的基于 UTF-16 的 .NET 字符串根据中指定的字符编码转换为外部程序的字节流。$OutputEncoding偏好变量 https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Preference_Variables#outputencoding,遗憾的是,Windows PowerShell 中默认为 ASCII(!),现在 PowerShell [Core] v6+ 中默认为(无 BOM)UTF-8。

    • 换句话说:通过指定的编码$OutputEncoding必须与外部程序期望的字符编码相匹配。

    • 反过来,它是指定的编码[Console]::OutputEncoding确定 PowerShell 如何解释收到的文本from一个外部程序,即它如何将接收到的字节转换为 .NET 字符串,逐行,剥离换行符(当在变量中捕获时,如果只输出一行,则等于单个字符串,或者等于一个array字符串)。

  • The 用于显示的表示你在 PowerShell 中看到控制台(终端)也是发送的内容to通过管道的外部程序,作为文本行,具体来说:

    • 如果一个对象(已经)is a string (or [char]实例)、PowerShell按原样将其发送到管道,但是总是附加适合平台的换行符.

      • 也就是说,在 Windows 上附加 CRLF 换行符,在类 Unix 平台上附加仅 LF 换行符。

      • 这种行为可能会产生问题,因为在某些情况下您会这样做not想要这样,并且没有办法阻止它 - 请参阅GitHub 问题 #5974 https://github.com/PowerShell/PowerShell/issues/5974, GitHub 问题 #13579 https://github.com/PowerShell/PowerShell/issues/13579, and 这个答案 https://stackoverflow.com/a/48372333/45375寻求解决方法。

    • If an object is, loosely speaking, a primitive type - something that is conceptually a single value, notably the various number types - it is stringified in a culture-sensitive manner, where available[3], a platform-appropriate newline is again invariably appended.

      • 例如,法国文化的影响(反映在Get-Culture), 小数1.2- PowerShell 将其解析为[double]值 - 发送为1,2<newline>.

      • 注意[bool]实例是not文化敏感且始终转换为字符串True or False.

    • 所有其他(复杂)类型均受 PowerShell 丰富的显示输出格式的约束,并且您在终端(控制台)中看到的内容也是发送到外部程序的内容 - 这不仅再次可能包含文化敏感的表示,而且通常存在问题,因为这些表示是为人类观察者设计的,而不是为程序化的加工。

The upshot:

  • 当心编码问题 - 确保$OutputEncoding and [Console]::OutputEncoding设置正确。

  • 为了避免意外的文化敏感性和意外的显示格式,最好故意地构造您要发送的字符串表示形式。


[1] By default; however, you can explicitly request buffering - expressed as an object count - via the common -OutBuffer parameter https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_CommonParameters#outbuffer

[2] On recent macOS and Linux platforms, the stdin buffer size is 64KB. On Unix-like platforms, utilities typically switch to line-buffering in interactive invocations, i.e. when the stream in question is connected to a terminal.

[3] The behavior is delegated to the .ToString() method of a type at hand, i.e. whether or not that method outputs a culture-sensitive representation.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Powershell 将数据传输到外部控制台应用程序 的相关文章

随机推荐

  • 获取有关 Linux 中“以太网电缆已插入”事件的通知

    我正在编写一个在 Linux 上运行的 Python 应用程序 我希望能够注册并成为notified如果系统网络电缆已插入 拔出 我已经在使用了pyUdev http packages python org pyudev api index
  • 从 npm 本地导入 ES 模块依赖项,无需捆绑/转译第一方源代码

    背景 我正在尝试创建一个 没有建造的 https www pika dev blog pika web a future without webpack JavaScript 应用程序 我不需要watch每次我保存任何源文件时 都会运行任务
  • 计算 pyspark 数据帧的百分比

    我有一个来自泰坦尼克号数据的 pyspark 数据框 我已将其副本粘贴在下面 如何添加包含每个存储桶百分比的列 谢谢您的帮助 首先是一个包含输入数据的文字 DataFrame import findspark findspark init
  • 环境变量更改project.json中的应用程序名称并设置运行时变量?

    我需要从相同的代码库生成两个应用程序 例如 pro 和 lite 版本 这里有很多关于此的问题 但我发现没有一个涉及node or electron 我只用过env以非常简单的方式进行开发 经过搜索后 我没有看到任何提到能够在已部署的应用程
  • 使用python从IB api获取外汇汇率

    我正在尝试使用 ibpy 库从交互式经纪商获取货币汇率 我在谷歌上找到了代码 我做了一些更改 from ib ext Contract import Contract from ib opt import ibConnection mess
  • 相对布局 - CenterInParent 和 marginTop

    我有以下 XML
  • 单击按钮后开始倒计时

    我正在创建一个带有计时器倒计时的儿童游戏 该游戏在用户单击按钮后开始 我正在使用的代码可以毫无问题地启动倒计时 但我希望倒计时仅在单击按钮后才开始 这是我的代码 window onload function function var cou
  • 触发 valueChange 与初始化值 - angular2

    我正在编写一个 angular2 应用程序 但我遇到了一些问题 首先 我有一个绑定到的选择formControl export class MyComponent implements OnInit profilesBy Observabl
  • 如何从 Java 运行 UNIX 终端并向其发送命令?

    关于主题 代码如下 Process proc null try String cmdss gnome terminal proc Runtime getRuntime exec cmdss null wd catch IOException
  • 防止iOS接近传感器使屏幕变黑

    我已经看到这个问题被问了几次 但没有人回答它 事实上这可能是不可能的 但我想知道是否有一种方法可以防止 iPhone 上的邻近状态发生变化时屏幕变黑 我已经实现了一种方法 可以在接近状态发生变化时执行某些操作 但屏幕会闪烁为黑色 我想避免这
  • Visual Studio 2013 中的自定义脚手架模板

    以前 使用 Visual Studio 2012 我能够将CodeTemplates文件夹到我的项目目录然后修改现有的T4 templates或者添加全新的 T4 模板来满足我特定的代码生成要求 前面描述的方法似乎不再适用于 Visual
  • numpy apply_along_axis 一维数组

    当 numpy apply along axis 采用一维数组作为输入时会发生什么 当我在一维数组上使用它时 我看到一些奇怪的东西 y array 1 2 3 4 第一次尝试 apply along axis lambda x x gt 2
  • AngularJs - RXJS 可观察取消订阅

    我已经设置了 RXJS 可观察的 我有两个组件订阅服务工厂中的一个主题 如何取消订阅选定组件的主题 以便按下按钮即可停止收听主题广播 看我的jsfiddle取消订阅应用程序 https jsfiddle net bkarv 0maek0qr
  • stdcall 可以有可变参数吗?

    据我所知 只有 caller clean stack 约定可以使用变量参数 顺便说一句 WinApi StringCchPrintfW 是这样声明的 我删除了 SAL 内联 HRESULT stdcall字符串CchPrintfW STRS
  • WidgetKit(意图)-如何链接从远程获取的多个动态意图?

    我正在为我的应用程序创建一个小部件 并使用从 API 获得的动态数据成功添加意图配置 此代码片段获取列表并将其返回到 Intent func provideLeagueOptionsCollection for intent LeagueC
  • 我可以注释“fun”声明的完整类型吗?

    在学习环境中 我可以选择哪些选项来为函数提供类型签名 标准 ML 没有像 Haskell 那样的顶级类型签名 以下是我考虑过的替代方案 模块签名 需要单独的签名文件 或者在与模块本身相同的文件内的单独块中定义的类型签名 这需要使用模块 在任
  • jquery 没有父级的子选择器

    我正在查看创建轮播菜单的教程中的一些代码 并注意到没有父项的父子选择器 以前从未见过这个 并且对它实际在做什么感到困惑 参见下面的代码 var wrapper gt div this css overflow hidden slider w
  • 生成最近两周的日期范围?

    我想生成 2 个 DATETIME 代表从星期日到星期六 2x 的最近两周 它不应该包括当前不完整的一周 感谢你的帮助 一些可以工作的东西 利用美妙的DateTime课程
  • Flutter上如何用pop获取返回值?

    我想知道如何在 Flutter 上使用 pop 获取两个值 我尝试编写代码 但我得到了异常 必须向文本小部件提供非空字符串 这是代码 第一屏 ElevatedButton child const Text move to second sc
  • Powershell 将数据传输到外部控制台应用程序

    我有一个可以接受标准输入的控制台应用程序 它缓冲数据直到执行命令 此时它会执行所有数据 并将输出发送到标准输出 目前 我正在从 Powershell 运行该应用程序 将命令通过管道传输到其中 然后解析输出 传入的数据相对较小 然而 该应用程