将管道输入定向到 Python 脚本的 PowerShell 包装器 [英] PowerShell wrapper to direct piped input to Python script

查看:106
本文介绍了将管道输入定向到 Python 脚本的 PowerShell 包装器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to write a little tool that will let me pipe command output to the clipboard. I've read through multiple answers on Stack Overflow, but they didn't work for me, because they didn't include piping, or because they didn't use a function, or they just threw errors (or maybe I just messed up). I threw up my hands with PowerShell and decided to go with Python.

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

I created a Python script called copyToClipboard.py:

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.)

(I haven't fully tested the argv[1] part, so that might be shaky. I'm mainly interested in reading from stdin, so the important part is sys.stdin.)

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

This works great! When I'm in the directory that contains the script, I can execute something like:

ls | python copyToClipboard.py

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

And the contents of ls magically appear on my clipboard. That's exactly what I want.

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

The challenge is wrapping this in a PowerShell function that will take a piped input and simply pass the input to the Python script. My goal is to be able to do ls | Out-Clipboard, so I created something like:

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

但这行不通.只有一行 $text 进入 Python 脚本.

But that doesn't work. Only one line of $text makes its way to the Python script.

如何构建 PowerShell 脚本的包装器,使其以 stdin 的形式接收到的任何内容都以 stdin 的形式传递给 Python 脚本?

How can I structure the wrapper for my PowerShell script such that whatever it receives as stdin simply gets passed to the Python script as stdin?

推荐答案

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

First, in PowerShell, a multi-line text is an array, so you need a [String[]] parameter. To solve your problem, try using the process block:

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 的进程块来处理它.在 TechNet.

I don't have Python here myself, so I can't test it. When you need to pass multiple items (an array) through the pipeline, you need the process block for PowerShell to handle it. More about process block and advanced functions is at TechNet.

这篇关于将管道输入定向到 Python 脚本的 PowerShell 包装器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆