Вопрос по python, powershell, stdin – Оболочка PowerShell для прямого конвейерного ввода в скрипт Python

1

Я пытаюсь написать небольшой инструмент, который позволит мне выводить команды в буфер обмена. Я'прочиталмножественный ответы на стекеПереполнение, но они нене работает для меня, потому что они неТрубопровод, или потому что они нене использовать функцию, или они просто выкидывали ошибки (или, может быть, я только что испортил). Я поднял руки с PowerShell и решил пойти с Python.

Я создал скрипт Python под названием: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.)

Это прекрасно работает! Когда я'м в каталоге, который содержит скрипт, я могу выполнить что-то вроде:

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 просто передается скрипту Python как?stdin

С помощью Ironpython вы можете вызвать родной.net методы так же, как вы делаете с PowerShell. Paulo Scardine
@BartekB Я понимаю, что яЯ делаю это неправильно. С более широкой точки зрения, я просто хочу сказать "Привет, функция Powershell: возьмите все, что пользователь дал вам как stdin, и передайте его этой функции python. Дон»ничего с этим не сделать. Просто передайте это. " Ben McCormack
Моя точка зрения была такой: когда вы пишете так, если вы на самом делетруба Что касается вашей функции, вы получите только последний объект в $ text. Вместо этого используйте автоматическую переменную $ input без какого-либо блока param (). Он должен содержать все, что вы отправляете в свою функцию. BartekB
Вы лжете своему пользователю, что поддерживаете значение из конвейера ..;) Для этого вам нужен блок process {} внутри вашей функции. Также я'Мы использовали несколько решений с [ClipBoard] :: SetText () и не имели проблем, поэтому, если вам действительно нужен PowerShell - я бы посоветовал проверить, что там происходит не так. Может быть, проблема с pipe / process {} тоже? BartekB

Ваш Ответ

1   ответ
2

в 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, чтобы справиться с этим. Подробнее о блоке процесса и расширенных функцияхна TechNet.

Похожие вопросы