title: Running Python Script at Startup to log mouse and keyboard activity in Linux
body: <p>I'm quite confident many people before asked this question or at least a similar question. My problem is a little bit problematic but it's simple. </p>
  
  <p>I've tried to run a Python script at startup with <code>cron</code> and by editing etc/rc.local file in Linux, but both ways failed to run my Python script. </p>
  
  <p>My script logs the activity of the keyboard and the mouse using listener objects for both keyboard and mouse. I use a third-party package called <code>pynput</code> which depends on <code>Xlib</code>. My script edits a file that requires <code>sudo</code> access, so I must run my script with <code>sudo</code>.</p>
  
  <p>You need to have a look at the script, so you know: </p>
  
  <pre><code>#!/usr/bin/env python
  #backlight.py
  
  from pynput.keyboard import Listener  as KeyboardListener
  from pynput.mouse    import Listener  as MouseListener
  
  import time
  
  STATUS = ""                # Keyboard backlight ON/OFF status
  turnOffSecs = 6           # Turn off keyboard backlight for x seconds of inactivity
  
  # Keyboard brightness control file (change to your directory)
  file_pth = "/sys/devices/platform/asus-nb-wmi/leds/asus::kbd_backlight/brightness"
  
  def get_LEVEL():
      """return the current level of brightness of keyboard backlight"""
      with open(file_pth, "r") as f:
          brightness_level = f.read()[0]
      return brightness_level
  
  
  class Sec_timer:
      """
      Sec_timer(until=None) 
          Create a timer that counts x number of seconds starting from 0
  
          until arg can be used for reseting the timer:
  
     *Example:
  
          timer = Sec_imer(20)
          while timer.elapsed &lt; timer.until:                  
              timer.count()                # count a second
          else:
              timer.reset_timer()          # reset timer on exit
      """
      def __init__(self, until=None):
          self.until = until
          self.elapsed = 0 
  
      def count_sec(self): 
          "Count one second per-call"
          time.sleep(1)
          self.elapsed += 1
  
      def reset_timer(self):
          self.elapsed = 0 
  
  
  
  timer = Sec_timer(turnOffSecs)           # Sec_timer(x) turn off keyboard backlight for x seconds of inactivity
  
  # General event handler to reset timer
  def reset_timer(*args):
      global STATUS
  
      timer.reset_timer()
      if STATUS == "OFF":
           # print(STATUS)
           with open(file_pth, "w") as f:
               f.write(current_brightnessLevel)
               f.close()
               STATUS="ON"
  
  
  
  keyboard_listener = KeyboardListener(on_press=reset_timer, 
                               on_release=(lambda *args: None))
  
  mouse_listener    = MouseListener(on_click=reset_timer, 
                               on_scroll=reset_timer, 
                               on_move=reset_timer)
  
  
  keyboard_listener.start()
  mouse_listener.start()
  
  
  while True:
      timer.count_sec()
      if timer.elapsed &gt; timer.until:
          # print "current brightness:" +  get_LEVEL()
          if  get_LEVEL() != "0":
              with open(file_pth, "w") as f: 
                  current_brightnessLevel = get_LEVEL()
                  f.write("0")
                  STATUS = "OFF"
  </code></pre>
  
  <p>This script logs the activity of the keyboard and the mouse, any keyboard or mouse activity will reset the timer. When x seconds passed and no keyboard or mouse activity took place, turn off the back light of the keyboard by writing "0" to the brightness folder. If any mouse or keyboard event takes place <code>after</code> the script turned off the back-light turn the keyboard brightness on according to the previous brightness level of the back-light. </p>
  
  <p>Running the script using terminal, it works perfectly fine. But, automating the launch of this script is tricky; here's what I tried so far: </p>
  
  <p>*Note, I've made the script file executable and backlight.py resides in <code>/home/user</code>:</p>
  
  <p>1) In terminal:</p>
  
  <pre><code>$ xhost +
  $ sudo ./backlight.py
  </code></pre>
  
  <p>Works fine!</p>
  
  <p>2) Using `etc/rc.local I added: </p>
  
  <pre><code>xhost + 
  cd /home/user/
  ./backlight.py
  </code></pre>
  
  <p>Script didn't run after reboot</p>
  
  <p>3) using <code>etc/rc.local</code></p>
  
  <p><code>$ sudo crontab -e</code></p>
  
  <pre><code>@reboot xhost +
  @reboot /home/user/backlight.py
  </code></pre>
  
  <p>Didn't run after reboot</p>
  
  <p>I had to execute <code>xhost +</code> because of a problem with <code>Xlib</code>. Using the last two ways didn't work. I'm guessing this is a programming problem and perhaps it has something to do with <code>Xlib</code>?!</p>
  
  <p>I know this script is insane in terms of interfacing with keyboard LEDS and call it "bad script" if you will. Though I'm just trying to solve a driver problem using file input/output solution, because I don't have the appetite to delve into Linux driver details, at least not for now!</p>