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.
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()
(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
And the contents of ls
magically appear on my clipboard. That's exactly what I want.
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
}
But that doesn't work. Only one line of $text
makes its way to the Python script.
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
?