【问题标题】:PowerShell wrapper to direct piped input to Python scriptPowerShell 包装器将管道输入定向到 Python 脚本
【发布时间】:2013-01-25 19:44:56
【问题描述】:

我正在尝试编写一个小工具,让我可以将命令输出通过管道传输到剪贴板。我已经阅读了 StackOverflow 上的multipleanswers,但它们对我不起作用,因为它们不包含管道,或者因为它们没有使用函数,或者它们只是抛出错误(或者可能我只是搞砸了)。我放弃了 PowerShell 并决定使用 Python。

我创建了一个名为 copyToClipboard.py 的 Python 脚本:

import sys
from Tkinter import Tk

if sys.stdin.isatty() and len(sys.argv) == 1:
  #We're checking for input on stdin and first argument
  sys.exit()

tk = Tk()
tk.withdraw()
tk.clipboard_clear()

if not sys.stdin.isatty():
    #We have data in stdin
    while 1:
        try:
            line = sys.stdin.readline()
        except KeyboardInterrupt:
            break

        if not line:
            break

        tk.clipboard_append(line)
elif len(sys.argv) > 1:
    for line in sys.argv[1]:
      tk.clipboard_append(line)


tk.destroy()

(我还没有完全测试argv[1] 部分,所以这可能会不稳定。我主要对阅读stdin 感兴趣,所以重要的部分是sys.stdin。)

这很好用!当我在包含脚本的目录中时,我可以执行如下操作:

ls | python copyToClipboard.py

ls 的内容神奇地出现在我的剪贴板上。这正是我想要的。

挑战在于将其包装在一个 PowerShell 函数中,该函数将接受管道输入并将输入简单地传递给 Python 脚本。我的目标是能够做到ls | Out-Clipboard,所以我创建了类似的东西:

function Out-ClipBoard() {
    Param(
      [Parameter(ValueFromPipeline=$true)]
      [string] $text
    )
    pushd
    cd \My\Profile\PythonScripts
    $text | python copyToClipboard.py
    popd
}

但这不起作用。只有一行 $text 进入 Python 脚本。

如何为我的 PowerShell 脚本构建包装器,以便它接收为 stdin 的任何内容都可以简单地以 stdin 的形式传递给 Python 脚本?

【问题讨论】:

  • 使用 ironpython,您可以像使用 powershell 一样调用本机 .net 方法。
  • 您在向您的用户撒谎说您支持管道中的价值。.. ;) 要做到这一点,您需要在函数中使用 process {} 块。另外:我使用 [ClipBoard]::SetText() 的解决方案很少,没有任何问题,所以如果你真的需要 PowerShell - 我建议检查那里出了什么问题。也许管道/流程{}也有问题?
  • @BartekB 我知道我做错了。从更大的角度来看,我只想说“嘿 Powershell 函数:将用户给你的任何内容作为标准输入并将其传递给这个 python 函数。不要对它做任何事情。只是传递它。”
  • 我的意思是:当这样写时,如果你真的pipe 任何东西到你的函数,你只会得到最后一个对象在$text 中管道。相反,使用自动变量 $input,没有任何 param () 块。它应该包含您通过管道传递给您的函数的任何内容。

标签: python powershell stdin


【解决方案1】:

首先,在 PowerShell 中,多行文本是一个数组,因此您需要一个 [String[]] 参数。要解决您的问题,请尝试使用进程块:

function Out-ClipBoard() {
    Param(
        [Parameter(ValueFromPipeline=$true)]
        [String[]] $Text
    )
    Begin
    {
        #Runs once to initialize function
        pushd
        cd \My\Profile\PythonScripts
        $output = @()
    }
    Process
    {
        #Saves input from pipeline.
        #Runs multiple times if pipelined or 1 time if sent with parameter
        $output += $Text
    }
    End
    {
        #Turns array into single string and pipes. Only runs once
        $output -join "`r`n" | python copyToClipboard.py
        popd
    }
}

我自己没有 Python,所以我无法测试它。当您需要通过管道传递多个项目(一个数组)时,您需要 PowerShell 的进程块来处理它。更多关于进程块和高级功能的信息是at TechNet

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    相关资源
    最近更新 更多