【问题标题】:How to pass large input to powershell如何将大输入传递给powershell
【发布时间】:2016-10-18 08:28:47
【问题描述】:

假设 powershell 在其命令中有 N 个字符的限制,我如何将 N 个以上的字符传递给 powershell cmdlet?基于https://support.microsoft.com/en-in/kb/830473 链接,似乎字符限制为8191,但它表示对于cmd.exe,不确定powershell 的大小限制是多少。因此,如果我的输入大小超过 >8k,是否可以将输入重定向到 powershell 以规避此问题(解决方案基于参考文档中提到的内容)。

例如:

powershell 控制台 $> echo “a very long string” // 整个命令,包括 echo 和 powershell 控制台上总计少于 8192 个字符的非常长的字符串。当我执行此操作时,我将整个字符串作为控制台上的输出

powershell console $> echo "a very long string // 尝试向非常长的字符串添加字符,如果总数超过 8192,powershell 不允许我向非常长的字符串添加更多字符,因为我猜我已达到我可以输入的字符数限制。

我想要什么:

powershell console $> echo // 将我的输入(超过 8192 个字符)放在一个文件中,并提供作为 echo 的输入,并且 echo 应该在控制台上显示完整的字符串,从而规避了数量的限制命令中的字符。

我使用的命令 echo 仅用于表示目的,我想使用自定义 cmdlet 代替,所以请认为这是一个有效的场景。

编辑 2:

psm1 文件:

Function DoSomething {

  [CmdletBinding()]
  Param(
    [Parameter(
     Mandatory = $False)
    ]
    [string]$v1,

    [Parameter(
     Mandatory = $False)
    ]
    [string]$v2)

    Begin {}

  Process {
    Write-Output "hello $v1 | $v2"
  }
}

文本文件内容说 content.txt(表示目的的缩写,但假设这可以超过 8k 个字符):

-v1 "t1" -v2 "qwe"

当我这样做的时候

powershell Console$> DoSomething (Get-Content content.txt)

我得到的输出是

hello -v1 "t1" -v2 "qwe" |

我希望输出是

hello -v1 "t1" | -v2 "qwe"

这样 cmdlet 的执行就可以毫无问题地进行。我以文本文件中超过 8k 个字符的示例进行了尝试,它能够打印输出,只是参数没有分开。向 cmdlet 提供输入的命令不必是 Get-Content,只要有效,它可以是任何命令。

【问题讨论】:

  • 您假设 PowerShell 对输入有限制,但此限制基于 CMD.EXE?那是因为您希望输入从 PowerShell 传递到 CMD.EXE,反之亦然?您能澄清一下您要运行的 cmdlet 吗?为我们提供具体的minimal reproducible example
  • @gravity 感谢您的回复。不,输入不会传递给 CMD.exe,反之亦然。我阅读了很多线程,我遇到了一个提到 8k 的线程。我给出了这个链接,因为它谈到了替代解释。对于您关于我要运行什么 cmdlet 的问题,所以我只是尝试回显“”,这是通过复制和扩展输入生成的随机字符串,我在 8175 附近的某个位置达到了极限,因此它更接近8192. 我最终可能会有超过 8k 的输入,因此需要考虑这一点。这是用于自定义 cmdlet。
  • 我还是建议给我们看minimal reproducible example。就限制而言,尚不完全清楚您遇到了什么。我有一个猜测,但如果问题不明确,我宁愿不回答。例如,我也不确定您为什么在 PowerShell cmdlet 中使用 echo
  • @gravity 我只关心输入的长度,所以如果我使用 echo 或其他东西有关系吗?我只有一个自定义 cmdlet,它接受各种输入参数并使用这些参数进行操作。并且这些输入参数可能会变得非常大,我只想确保不达到一定数量字符的 powershell 限制。我已经用某种例子编辑了这个问题。让我知道这是否使它更清楚一点。
  • 您是否有实际问题需要解决,或者您只是要求我们为您进行测试?

标签: powershell


【解决方案1】:

您误解了 PowerShell 函数中的参数是如何工作的。 Get-Content 的输出是一个字符串数组(文件中的每一行一个字符串),但整个数组传递给第一个参数。此外,字符串不会被神奇地拆分,以便子字符串可以转到多个参数。 PowerShell 应该如何知道拆分字符串的方式?

处理此类输入数据的更好方法是让您的函数接受来自管道的输入:

Function DoSomething {
  [CmdletBinding()]
  Param(
    [Parameter(
      Mandatory=$false,
      ValueFromPipeline=$true,
      ValueFromPipelineByPropertyName=$true
    )]
    [string]$v1,

    [Parameter(
      Mandatory=$false,
      ValueFromPipeline=$true,
      ValueFromPipelineByPropertyName=$true
    )]
    [string]$v2
  )

  Process {
    Write-Output "hello $v1 | $v2"
  }
}

并将数据定义为 CSV(与参数名称匹配的列名称):

v1,v2
"-v1 ""t1""","-v2 ""qwe"""

这样您就可以将数据通过管道传输到函数中:

Import-Csv content.csv | DoSomething

使用这样构建的函数,您还可以将数据定义为哈希表和splat它:

$data = @{
  'v1' = '-v1 "t1"'
  'v2' = '-v2 ""qwe"'
}

DoSomething @data

有关函数参数的更多信息,请参阅about_Parametersabout_Functions_Advanced_Parameters

【讨论】:

  • 嗯,有道理,感谢您的解释。因此,对于我的场景,有很多类似于 DoSomething 的 cmdlet,但没有为其设置 ValuefromPipeline 属性。此外,到目前为止,输入已通过直接将其传递给 cmdlet(如“DoSomething ”)进行处理,但就在最近我们发现输入可能会增长到大于 8k,因此需要一种不同的方法不必修改输入的方式以及现有 cmdlet 的编写方式。所以我在想是否有像“DoSomething
  • ... 如果可行的话,对我来说是完美的。我知道这可能是不可能的,但我只是想知道是否有任何方法可以完成,因为更改 cmdlet 和输入对于我的场景可能不可行。
【解决方案2】:

否则,您可以传递一个路径文件,该文件的内容在您的脚本 ps 中使用。那就没有限制了……

【讨论】:

  • 感谢您的回复。我不确定您所说的路径文件是什么意思。能详细点吗?
猜你喜欢
  • 2022-01-23
  • 2022-08-15
  • 2020-08-31
  • 1970-01-01
  • 2021-09-11
  • 2017-08-16
  • 1970-01-01
  • 2021-08-26
  • 1970-01-01
相关资源
最近更新 更多