Why is this python script running in background consuming 100 % CPU?
You forgot the time.sleep()
in your while
loop, according to this answer on SO sleeping for 0.2s is a good compromise between polling frequency and CPU load:
import time
while True:
get_clipboard()
time.sleep(0.2) # sleep for 0.2 seconds
Checking the clipboard every 0.2 seconds seems easily often enough; if you want less CPU load you can even increase this value – few users change the clipboard content from one second to another.
Note that in general polling in a loop as often as that is not considered good design. A better approach would be to act on the event of changing the clipboard content, an example for GTK can be found in this SO answer.
Further reading
- linuxconfig.org article on Python While Loops
- cyberciti.biz article on
time.sleep()
-
blog article on How To Make Python Wait discussing different ways, some of which are much more elaborate and flexible than the static
time.sleep()
I finally make it work a without loop. This is the code:
I had to install few modules: sudo apt install python3-gi python3-gi-cairo gir1.2-gtk-3.0
#!/usr/bin/env python3
import gi, sys
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk
last_clipboard = ""
def callBack(*args):
global last_clipboard
new_clipboard = clip.wait_for_text()
if new_clipboard != last_clipboard:
last_clipboard = new_clipboard
print("new Clipboard")
print(new_clipboard)
clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
clip.connect('owner-change',callBack)
Gtk.main()
feel free to choose the solution that fits for you.
You are running the thing in a while True:
loop! That means that the CPU is constantly running your loop. Just add a small pause there and you should see the CPU usage drop precipitously:
#!/usr/bin/env python
import Tkinter
import time
last_clipboard = ""
def get_clipboard():
global last_clipboard
root = Tkinter.Tk()
root.withdraw() # Hide the main window (optional)
text_in_clipboard = root.clipboard_get()
if text_in_clipboard != last_clipboard:
last_clipboard = text_in_clipboard
print last_clipboard
while True:
get_clipboard()
time.sleep(1)
I was intrigued by this project so wrote a bash script for those more comfortable in that environment:
#!/bin/bash
xclip -o -sel clip > /tmp/LastClip
while true ; do
xclip -o -sel clip > /tmp/NewClip
diff -q /tmp/LastClip /tmp/NewClip > /tmp/DiffClip
if [[ -s /tmp/DiffClip ]] ; then
cat /tmp/NewClip # For testing dump to screen instead of printing
cp -a /tmp/NewClip /tmp/LastClip
fi
sleep 1.0
done
It does require Xorg's xclip
package:
sudo apt install xclip
It's dumping clipboard contents to screen using cat
command. If you want hard copy instead replace cat
with lp
and specify your printer name, orientation and possibly "fit to page" option.
You will see a bit of lag to screen because I choose sleep 1.0
which would be unnoticeable with a printer and still faster than people can highlight text and use Ctrl+C.
If you copy the exact same highlighted text to the clipboard it doesn't trigger a difference. One letter more or less will trigger a response.