Having trouble interacting with the clipboard from python (or pasteboard as mac os calls it) from Python. Running High Sierra.
Found some examples:
http://code.activestate.com/recipes/410615/
http://www.devx.com/opensource/Article/37233/0/page/3
However it seems like they're using deprecated tools that I can't load.
Scrap exists but seems to lack the GetCurrentScrap method:
>>> import Carbon.Scrap
>>> from Carbon.Scrap import GetCurrentScrap
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name GetCurrentScrap
>>>
Thanks
EDIT
removed part of the question that was erroneous
I use this:
import subprocess
def getClipboardData():
p = subprocess.Popen(['pbpaste'], stdout=subprocess.PIPE)
retcode = p.wait()
data = p.stdout.read()
return data
def setClipboardData(data):
p = subprocess.Popen(['pbcopy'], stdin=subprocess.PIPE)
p.stdin.write(data)
p.stdin.close()
retcode = p.wait()
Related
This question already has answers here:
subprocess.Popen stdin read file
(3 answers)
Closed 6 years ago.
for a little project of my own, I am trying to write a program that prints out the contents of a file on the computers default printer.
I know theres alot of similar questions around, but none of them works on my pc (Linux mint 17.3)
here is one that I tried, it got the closest to what i needed:
from subprocess import Popen
from cStringIO import StringIO
# place the output in a file like object
sio = StringIO("test.txt")
# call the system's lpr command
p = Popen(["lpr"], stdin=sio, shell=True)
output = p.communicate()[0]
this gives me the following error:
Traceback (most recent call last):
File "/home/vandeventer/x.py", line 8, in <module>
p = Popen(["lpr"], stdin=sio, shell=True)
File "/usr/lib/python2.7/subprocess.py", line 702, in __init__
errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
File "/usr/lib/python2.7/subprocess.py", line 1117, in _get_handles
p2cread = stdin.fileno()
AttributeError: 'cStringIO.StringI' object has no attribute 'fileno'
Doe anyone out there know hoe one could implement this in python? it really does not have to work on windows
Regards
Cid-El
you don't have to use StringIO for this. Just use the pipe feature of subprocess and write your data to p.stdin:
from subprocess import Popen
# call the system's lpr command
p = Popen(["lpr"], stdin=subprocess.PIPE, shell=True) # not sure you need shell=True for a simple command
p.stdin.write("test.txt")
output = p.communicate()[0]
as a bonus, this is Python 3 compliant (StringIO has been renamed since :))
BUT: that would just print a big white page with one line: test.txt. lpr reads standard input and prints it (that's still an interesting piece of code :))
To print the contents of your file you have to read it, and in that case it's even simpler since pipe & files work right away together:
from subprocess import Popen
with open("test.txt") as f:
# call the system's lpr command
p = Popen(["lpr"], stdin=f, shell=True) # not sure you need shell=True for a simple command
output = p.communicate()[0]
I am new to Python and have searched high and low for an example of how to process the STDOUT of a subprocess, but with no luck.
I have a test command line executable that produces output continually and am trying to read the STDOUT in real-time and print this to the screen. Eventually it will process the data locally and then send a summary onto another machine, but I have simplified this down to ask this question.
I have tried to use Python to do this as shown in the code below:
import subprocess, time, os, sys
cmd = [sys.executable, 'TestStdOut.exe']
p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
for line in iter(p.stdout.readline, b''):
print(">>> " + line)
The test executable I am using just outputs dateTime for the moment, and the stdout looks like this:
....
16/11/2015 10:52:44
16/11/2015 10:52:44
16/11/2015 10:52:44
16/11/2015 10:52:44
16/11/2015 10:52:44
16/11/2015 10:52:45
....
But I am getting this error and I cannot work out why:
Traceback (most recent call last):
File "test_stdout.py", line 9, in <module>
print(">>> " + line)
TypeError: Can't convert 'bytes' object to str implicitly
I was expecting the Python to simply display the same lines as if I ran the executable from the command line. I have googled the error, but I cannot seem to find an answer.
What am I missing?
Many thanks
Pete
UPDATE : Thanks to 2RING I went back and reviewed my notes, this code now works:
import subprocess, time, os, sys
cmd = ['TestStdOut.exe']
p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
while True:
line = p.stdout.readline()
if line != '':
print(line.rstrip().decode('utf-8'))
else:
break
I am playing with the subprocess library. I can perform
v = subprocess.check_output("ls")
and it works fine. However, when I SSH into a machine and I want to perform a hadoop command,
v = subprocess.check_output("hadoop fs -ls /path/to/file* | grep -oE '/(.*)'")
I get
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'check_output'
Not quite sure why. I think it might be my lack of understanding of subprocess. How can i fix this error?
check_output was introduced in python 2.7 so won't work for < 2.7.
You can use Popen with communicate to get the output.
from subprocess import PIPE,Popen
proc = Popen(['ls', '-l'], stdout=PIPE)
print(proc.communicate()[0].split())
This part of the docs may be useful
Here is my version of subprocess.check_output function for Python 2.6 and it supports pipe lines along with habitual command interface.
import subprocess
def check_output(cmd):
""" https://docs.python.org/2/library/subprocess.html#subprocess.Popen
Implementation subprocess.check_output() for Python 2.6
"""
process_list = []
cmd_list = cmd.strip().split("|")
for i, sub_cmd in enumerate(cmd_list):
STDIN = None
if i > 0:
STDIN = process_list[i - 1].stdout
process_list.append(subprocess.Popen(sub_cmd, stdin=STDIN, stdout=subprocess.PIPE, shell=True))
if len(process_list) == 0:
return ''
output = process_list[i].communicate()[0]
return output
Test call:
print check_output('ls -la /var | grep log')
Output:
drwxr-xr-x 1 root root 4096 Dec 11 13:22 log
padraic-cunningham, while your answer got me part of the way there, in my case the command is an SSH command. Since communicate kills my process prematurely(as soon as it reads an EOF character), I've found the following works better:
import subprocess
def check_output(command_list):
proc = subprocess.Popen(command_list, stdout=subprocess.PIPE)
proc.wait()
return proc.stdout.read()
I have the following code where I am trying to check for directory "Gerrits/HEAD/wlan" and then do some operations,for some reason if condition to check for the directory keeps failing even thought the directory exists?
anything wrong with the if condition#if (os.path.isdir(SCRIPT_ROOT + "/Gerrits/HEAD/wlan")): below
import os
import subprocess
from subprocess import check_call
SCRIPT_ROOT=subprocess.Popen(['pwd'], stdout=subprocess.PIPE).communicate()[0]
print SCRIPT_ROOT
def main ():
if (os.path.isdir(SCRIPT_ROOT + "/Gerrits/HEAD/wlan")):
print "SCRIPT_ROOT/Gerrits/HEAD/wlan already exists,cloning it again to the tip"
check_call("rm -rf $SCRIPT_ROOT/Gerrits/HEAD/wlan ", shell=True)
check_call("cd Gerrits/HEAD",shell=True)
else:
print "SCRIPT_ROOT/Gerrits/HEAD/wlan doesn't exist,cloning it"
os.makedirs("Gerrits/HEAD/wlan")
check_call("cd Gerrits/HEAD",shell=True)
currdir=subprocess.Popen(['pwd'], stdout=subprocess.PIPE).communicate()[0]
if __name__ == '__main__':
main()
Error:-
SCRIPT_ROOT/Gerrits/HEAD/wlan doesn't exist,cloning it
Traceback (most recent call last):
File "test.py", line 21, in <module>
main()
File "test.py", line 16, in main
os.makedirs("Gerrits/HEAD/wlan")
File "/usr/lib/python2.6/os.py", line 157, in makedirs
mkdir(name, mode)
OSError: [Errno 17] File exists: 'Gerrits/HEAD/wlan'
Add .strip() to your communicate()[0] calls, the code as is includes trailing newline in the output.
Just to be sure, your script that I just tested on a linux box with Python 2.5.
import os
import subprocess
from subprocess import check_call
SCRIPT_ROOT=subprocess.Popen(['pwd'], stdout=subprocess.PIPE).communicate()[0].strip()
print SCRIPT_ROOT
def main ():
if (os.path.isdir(SCRIPT_ROOT + "/Gerrits/HEAD/wlan")):
print "SCRIPT_ROOT/Gerrits/HEAD/wlan already exists,cloning it again to the tip"
check_call("rm -rf %s/Gerrits/HEAD/wlan" % SCRIPT_ROOT, shell=True)
check_call("cd Gerrits/HEAD",shell=True)
else:
print "SCRIPT_ROOT/Gerrits/HEAD/wlan doesn't exist,cloning it"
os.makedirs("Gerrits/HEAD/wlan")
check_call("cd Gerrits/HEAD",shell=True)
currdir=subprocess.Popen(['pwd'], stdout=subprocess.PIPE).communicate()[0].strip()
if __name__ == '__main__':
main()
And its output:
vlazarenko#xx:~$ python o.py
/media/home/vlazarenko
SCRIPT_ROOT/Gerrits/HEAD/wlan already exists,cloning it again to the tip
When I execute this line of code here:
SCRIPT_ROOT=subprocess.Popen(['pwd'], stdout=subprocess.PIPE).communicate()[0]
...the value of SCRIPT_ROOT has a trailing newline
>>> import os
>>> import subprocess
>>> ROOT = subprocess.Popen(['pwd'], stdout=subprocess.PIPE).communicate()[0]
>>> ROOT
'/Users/bgporter/personal\n'
...which makes this call
if (os.path.isdir(SCRIPT_ROOT + "/Gerrits/HEAD/wlan")):
behave differently than you'd like it to. You can either call strip() on that value, or if you always want to get the current working directory, you can do that much more easily by calling os.getcwd()
Similarly, you can use the os.removedirs() function to recursively remove the directories you don't want instead of shelling out.
I use subprocess exchange data between two process
I edit a repeat.py file with:
this file is a example from http://www.doughellmann.com/PyMOTW/subprocess/
import sys
sys.stderr.write('repeater.py: starting\n')
sys.stderr.flush()
while True:
next_line = sys.stdin.readline()
if not next_line:
break
sys.stdout.write(next_line)
sys.stdout.flush()
sys.stderr.write('repeater.py: exiting\n')
sys.stderr.flush()
and run this file in ipython
In [1]: import subprocess
In [2]: f=subprocess.Popen(['python','~/repeat.py'],shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE)
In [3]: f.stdin.write('teststs\n')
In [4]: f.communicate()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'teststs' is not defined
Out[4]: ('', None)
why teststs is not defined?
You seem to be starting an interactive Python session instead of running repeat.py. Try removing shell=True, it doesn't make sense together with a list of parameters. (Using shell=True is almost always a bad idea, by the way.)
This works with some strange behavior at first 5 key-presses. I don't know why. After that if works fine, and we have access to ls -l, cd, previous commands when press UP, seems command line has full functionality.
#!/bin/python3
import subprocess
import sys
proc = subprocess.Popen(['bash'])
while True:
buff = sys.stdin.readline()
stdoutdata, stderrdata = proc.communicate(buff)
if( stdoutdata ):
print( stdoutdata )
else:
print('n')
break
Here is my similar question.