moses-palmer / pynput

Sends virtual input commands
GNU Lesser General Public License v3.0
1.79k stars 248 forks source link

Cannot import pynput via crontab on ubuntu #423

Closed melgazar9 closed 2 years ago

melgazar9 commented 2 years ago

Description Take a hello world example - I create a simple tmp.py script that just prints "hi" to the screen. When i run this script after a fresh pip install, it works fine. I ensured I am using the exact same version of pip in the crontab file that I am using in the terminal when calling python directly.

Platform and pynput version I'm on Ubuntu 20.0.4 LTS and my version of pynput == 1.7.4.

To Reproduce In a terminal type the following

$ python -V
Python 3.8.8

$ pip -V
pip 21.3.1 from /home/melgazar9/anaconda3/lib/python3.8/site-packages/pip (python 3.8)

$ which python
/home/melgazar9/anaconda3/bin/python

As you can see, the pip and python versions are aligned. Next, create a file called tmp.py with the following code.

from pynput.keyboard import Key, Listener
print('hi')

Once the file is saved, close the terminal run the code

$ python tmp.py 
hi

Next, create a cronjob that runs tmp.py every minute and logs the output to hi.out and hi_errors.out. Before running crontab -e, ensure this line works in the terminal.

cd && "$(which python)" tmp.py >> hi.out 2>> hi_errors.out

It outputs hi to hi.out and no errors to hi_errors.out

(base) melgazar9@matts-system:~$ cat hi_errors.out 
(base) melgazar9@matts-system:~$ cat hi.out 
hi

Now try it with the crontab. crontab -e

* * * * * cd && "$(which python)" tmp.py >> hi.out 2>> hi_errors.out

After one minute you will see hi.out not populated with the new run (only one output of hi from the old run), and hi_errors.out populated with the following error.

(base) melgazar9@matts-system:~$ cat hi.out 
hi
(base) melgazar9@matts-system:~$ cat hi_errors.out 
Traceback (most recent call last):
  File "/home/melgazar9/tmp.py", line 1, in <module>
    from pynput.keyboard import Key, Listener
ModuleNotFoundError: No module named 'pynput'
(base) melgazar9@matts-system:~$ 
moses-palmer commented 2 years ago

Thank you for your report.

I think this is caused by the environment under which the cron command is run; if you were to print all environment variables in the job, you would probably find that it is not the anaconda version of Python that is executed.

With that said, running anything using pynput from a crontab will probably not work in the general case; unless your requirements are such that you can use the uinput backend, you will be using the xorg backend, which requires that the environment is set up to launch an X client, and this is mostly not the case in periodic background tasks.

I will close this issue as it is not specific to this library, and with a hope that you will be able to accomplish your task with the pointers in this message.