279

I just need a python script that copies text to the clipboard.

After the script gets executed i need the output of the text to be pasted to another source. Is it possible to write a python script that does this job?

M. A. Kishawy
  • 5,001
  • 11
  • 47
  • 72
iamsiva11
  • 2,919
  • 2
  • 15
  • 9
  • 4
    This has been asked many times. Have you tried [searching for Python+Windows+clipboard?](http://stackoverflow.com/search?q=python+windows+clipboard) – Junuxx Jun 16 '12 at 12:44
  • If you're looking to do this on Linux, see: [How to share clipboard data between processes in GTK?](https://stackoverflow.com/questions/53675434/how-to-share-clipboard-data-beetween-processes-in-gtk/57522486). – bitinerant Aug 16 '19 at 09:53
  • 5
    please reopen: the linked question covers Windows; this is general. – Jason S Apr 21 '20 at 16:13

8 Answers8

342

See Pyperclip. Example (taken from Pyperclip site):

import pyperclip
pyperclip.copy('The text to be copied to the clipboard.')
spam = pyperclip.paste()

Also, see Xerox. But it appears to have more dependencies.

vauhochzett
  • 2,732
  • 2
  • 17
  • 40
robert
  • 33,242
  • 8
  • 53
  • 74
  • 2
    I tried it on my system, and .setcb doesn't work, but .copy does. I'm using pyperclip 1.5.4 on py 2.7. Just in case someone runs into the same problems - and @robert, I'd love to hear why this syntax works on your system but doesn't on mine. – Vincent Tjeng Sep 28 '14 at 18:20
  • 1
    .copy seems to be the offical one. https://github.com/asweigart/pyperclip – fnkr Oct 17 '14 at 19:50
  • If the copied text doesn't persist after running from the script, refer to [this issue](https://github.com/asweigart/pyperclip/issues/61#issuecomment-415934948) for the solution. – xtluo Jun 10 '19 at 07:28
  • `xerox` worked for me on `kubunutu 20.04`; see [here](https://stackoverflow.com/a/75858604/11932107). – linguisticturn Mar 27 '23 at 17:27
  • Important note mentioned in the Readme: `Currently only handles plaintext. On Windows, no additional modules are needed. On Mac, this module makes use of the pbcopy and pbpaste commands, which should come with the os. On Linux, this module makes use of the xclip or xsel commands, which should come with the os. Otherwise run "sudo apt-get install xclip" or "sudo apt-get install xsel" (Note: xsel does not always seem to work.) Otherwise on Linux, you will need the gtk or PyQt4 modules installed.` So check for dependencies on your platform/system. – LegendaryCodingNoob Jun 27 '23 at 04:22
135

On macOS, use subprocess.run to pipe your text to pbcopy:

import subprocess 
data = "hello world"
subprocess.run("pbcopy", text=True, input=data)

It will copy "hello world" to the clipboard.

Laszlo Treszkai
  • 332
  • 1
  • 12
kyle k
  • 5,134
  • 10
  • 31
  • 45
31

To use native Python directories, use:

import subprocess

def copy2clip(txt):
    cmd='echo '+txt.strip()+'|clip'
    return subprocess.check_call(cmd, shell=True)

on Mac, instead:

import subprocess

def copy2clip(txt):
    cmd='echo '+txt.strip()+'|pbcopy'
    return subprocess.check_call(cmd, shell=True)

Then use:

copy2clip('This is on my clipboard!')

to call the function.

Community
  • 1
  • 1
Binyamin
  • 669
  • 8
  • 17
  • 2
    CalledProcessError Traceback (most recent call last) in () 4 cmd='echo '+txt.strip()+'|clip' 5 return subprocess.check_call(cmd, shell=True) ----> 6 copy2clip('This is on my clipboard!') in copy2clip(txt) 3 def copy2clip(txt): 4 cmd='echo '+txt.strip()+'|clip' ----> 5 return subprocess.check_call(cmd, shell=True) ... CalledProcessError: Command 'echo This is on my clipboard!|clip' returned non-zero exit status 127 –  Dec 16 '16 at 19:28
  • this works, but on windows, `clip` is a windows only command (and sometimes it's not part of the system, you have to download & install it manually on WinXP) – Jean-François Fabre May 16 '18 at 19:25
  • 3
    Seems good but has an extra '\n'. – Seaky Lone Jan 20 '19 at 21:22
  • 1
    One thing is the extra '\n' and the other is that I had problems when copying linux commands, e.g. 'kill 1026 && kill 982'. pyperclip did the job in the end. – Niko Apr 25 '19 at 08:59
  • 12
    This is a security hazard, because it is vulnerable to shell injection attacks. – Hatshepsut May 08 '19 at 03:50
  • @Hatshepsut You can write the data to a temporary file and feed clip the file path instead. This both mitigates the shell injection security risk and also simplifies shell character escape issues ("if you use the method in the answer and want to copy text with double quotes, it becomes more complex") – Shmuel Kamensky Jun 20 '20 at 10:54
  • @O.rka Same for me. I'm on Debian Linux. – Palbitt Sep 08 '20 at 22:18
  • 2
    -1. Shelling out is a sensible way to handle this, but as @Hatshepsut says the sample code is *extremely* dangerous and unreliable, even if someone is not actively trying to hack something. There are all kinds of things you could have on your clipboard that could inadvertently run commands or at least cause syntax errors. – Soren Bjornstad Oct 03 '20 at 17:50
  • Add the `-n` flag to `echo` command to remove the trailing `\n`. ie: `f'echo -n {txt.strip()}|clip'` – Lucas Sousa Jul 27 '23 at 18:24
  • I still had some problems with `echo`. My `\n` problem was solved with using `printf` instead: `f'printf {txt.strip()}|clip'`. – Lucas Sousa Jul 31 '23 at 14:50
  • Note: To handle multi-line strings you need to format your command differently per https://stackoverflow.com/a/66548057/5758534. The code as is will just not work for multi-line strings. – Callahan Aug 11 '23 at 13:58
12

PyQt5:

from PyQt5.QtWidgets import QApplication
import sys

def main():
    app = QApplication(sys.argv)
    cb = QApplication.clipboard()
    cb.clear(mode=cb.Clipboard )
    cb.setText("Copy to ClipBoard", mode=cb.Clipboard)
    # Text is now already in the clipboard, no need for further actions.
    sys.exit()

if __name__ == "__main__":
    main()
Community
  • 1
  • 1
Akshay
  • 463
  • 6
  • 15
  • 2
    If you are using `QApplication.clipboard()` you don't need to import `QClipboard`. – Saelyth Jan 16 '19 at 00:10
  • This also works really great if using PySimpleGUIQt `cb = sg.QtGui.QClipboard() cb.clear(mode=cb.Clipboard) cb.setText(values["-DATA-"])` – JoeW Jun 12 '22 at 13:26
6

GTK3:

#!/usr/bin/python3

from gi.repository import Gtk, Gdk


class Hello(Gtk.Window):

    def __init__(self):
        super(Hello, self).__init__()
        clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
        clipboard.set_text("hello world", -1)
        Gtk.main_quit()


def main():
    Hello()
    Gtk.main()

if __name__ == "__main__":
    main()
Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
5

I try this clipboard 0.0.4 and it works well.

https://pypi.python.org/pypi/clipboard/0.0.4

import clipboard
clipboard.copy("abc")  # now the clipboard content will be string "abc"
text = clipboard.paste()  # text will have the content of clipboard
Du Peng
  • 351
  • 3
  • 3
2

One more answer to improve on: https://stackoverflow.com/a/4203897/2804197 and https://stackoverflow.com/a/25476462/1338797 (Tkinter).

Tkinter is nice, because it's either included with Python (Windows) or easy to install (Linux), and thus requires little dependencies for the end user.

Here I have a "full-blown" example, which copies the arguments or the standard input, to clipboard, and - when not on Windows - waits for the user to close the application:

import sys

try:
    from Tkinter import Tk
except ImportError:
    # welcome to Python3
    from tkinter import Tk
    raw_input = input

r = Tk()
r.withdraw()
r.clipboard_clear()

if len(sys.argv) < 2:
    data = sys.stdin.read()
else:
    data = ' '.join(sys.argv[1:])

r.clipboard_append(data)

if sys.platform != 'win32':
    if len(sys.argv) > 1:
        raw_input('Data was copied into clipboard. Paste and press ENTER to exit...')
    else:
        # stdin already read; use GUI to exit
        print('Data was copied into clipboard. Paste, then close popup to exit...')
        r.deiconify()
        r.mainloop()
else:
    r.destroy()

This showcases:

  • importing Tk across Py2 and Py3
  • raw_input and print() compatibility
  • "unhiding" Tk root window when needed
  • waiting for exit on Linux in two different ways.
Community
  • 1
  • 1
Tomasz Gandor
  • 8,235
  • 2
  • 60
  • 55
2

This is an altered version of @Martin Thoma's answer for GTK3. I found that the original solution resulted in the process never ending and my terminal hung when I called the script. Changing the script to the following resolved the issue for me.

#!/usr/bin/python3

from gi.repository import Gtk, Gdk
import sys
from time import sleep

class Hello(Gtk.Window):

    def __init__(self):
        super(Hello, self).__init__()
        
        clipboardText = sys.argv[1]
        clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
        clipboard.set_text(clipboardText, -1)
        clipboard.store()


def main():
    Hello()
    
    

if __name__ == "__main__":
    main()

You will probably want to change what clipboardText gets assigned to, in this script it is assigned to the parameter that the script is called with.

On a fresh ubuntu 16.04 installation, I found that I had to install the python-gobject package for it to work without a module import error.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Programster
  • 12,242
  • 9
  • 49
  • 55