我正在尝试编写一个小工具,让我将命令输出传递给剪贴板。我已经在Stack Overflow上阅读了multiple answers,但它们对我不起作用,因为它们不包括管道,或者因为它们没有使用功能,或者它们只是扔了错误(或者我只是搞砸了)。我向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脚本?
答案 0 :(得分: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的流程块来处理它。有关流程块和高级功能的更多信息,请at TechNet。