PowerShell包装器,用于将管道输入定向到Python脚本
我正试图编写一个小工具,让我管道命令输出到剪贴板。我已经通读了StackOverflow,但它们对我不起作用,因为它们不包括管道,或者因为它们没有使用函数,或者它们只是抛出了错误(或者可能是我搞砸了)。我放弃了PowerShell,决定使用Python 我创建了一个名为PowerShell包装器,用于将管道输入定向到Python脚本,python,powershell,stdin,Python,Powershell,Stdin,我正试图编写一个小工具,让我管道命令输出到剪贴板。我已经通读了StackOverflow,但它们对我不起作用,因为它们不包括管道,或者因为它们没有使用函数,或者它们只是抛出了错误(或者可能是我搞砸了)。我放弃了PowerShell,决定使用Python 我创建了一个名为copytolipboard.py的Python脚本: import sys from Tkinter import Tk if sys.stdin.isatty() and len(sys.argv) == 1: #We'
copytolipboard.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
function Out-ClipBoard() {
Param(
[Parameter(ValueFromPipeline=$true)]
[string] $text
)
pushd
cd \My\Profile\PythonScripts
$text | python copyToClipboard.py
popd
}
而ls
的内容神奇地出现在我的剪贴板上。这正是我想要的
挑战在于将其包装到一个PowerShell函数中,该函数将接受管道输入并将输入传递给Python脚本。我的目标是能够在剪贴板上执行ls | Out
,因此我创建了如下内容:
ls | python copyToClipboard.py
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脚本?首先,在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的进程块来处理它。有关进程块和高级函数的更多信息,请参见。使用ironpython,您可以调用本机
.net
方法,就像您使用powershell一样。您在向用户撒谎,说您支持来自管道的值……)要做到这一点,您需要在函数中使用进程{}块。另外:我在[ClipBoard]::SetText()上使用了一些解决方案,没有任何问题,所以如果您真的需要PowerShell,我建议您检查哪里出了问题。也许管道/进程{}也有问题?我知道我做错了。从更大的角度来看,我只想说“嘿,Powershell函数:将用户给你的任何东西作为stdin传递给这个python函数。不要对它做任何事情。只传递它。”我的观点是:当这样编写时,如果你真的将任何东西传递给你的函数,你只会得到最后一个以$text形式传递的对象。相反,使用自动变量$input,不带任何param()块。它应该包含您通过管道传递到函数的任何内容。