PowerShell封装以将管道输入导入Python脚本
我正在尝试写一个小工具,让我可以把命令的输出直接复制到剪贴板。我在Stack Overflow上看了很多相关的回答,但是都没能解决我的问题,因为它们没有涉及到管道,或者没有使用函数,或者直接报错(也可能是我自己搞错了)。所以我放弃了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
都能直接传递给Python脚本作为stdin
呢?
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 看看。