Search code examples
servicecommand-line-interfaceshsystemd

How to execute this command in systemd servicefile?


Ok, so I have this command that turns off my touchscreen. It works when I execute it in a root shell.

So this works:

sudo su
/usr/bin/echo $(ls /sys/bus/hid/drivers/hid-multitouch | awk NR==1'{print $1}') > /sys/bus/hid/drivers/hid-multitouch/unbind

And then my touchscreen stops working, which is the result that I wanted.

Now I want to make a touchscreen.service file to execute this on every boot. So in the service file I include:

ExecStart=/usr/bin/echo $(ls /sys/bus/hid/drivers/hid-multitouch | awk NR==1'{print $1}') > /sys/bus/hid/drivers/hid-multitouch/unbind

However it isn't working > nor throwing any errors that I've been able to catch.

I do know from earlier fidlings with .service files that I might actually need to use /usr/bin/sh -c, so I have also tried:

ExecStart=/usr/bin/sh -c "/usr/bin/echo $(ls /sys/bus/hid/drivers/hid-multitouch | awk NR==1'{print $1}') > /sys/bus/hid/drivers/hid-multitouch/unbind"

Yet this also doesn't work.. maybe because of the awk NR==1'{print $1}'part? I have also tried replacing it with awk NR==1'\''{print $1}'\''but again it fails to work.

Does anyone have any ideas on how to get the command that is working in my root cli environment to also work as a systemd service?


Solution

  • To start with,

    1. The syntax of the awk command is just wrong. The quotes are incorrectly placed. The part NR == 1 is part of the awk command to indicate the first line record in the file, i.e.
      awk NR==1'{print $1}'
      #  ^^^^^^^  should be within quotes
      awk 'NR == 1 { print $1 }'
      
    2. Your sequence of echo, ls and the command substitution $(..) doesn't look right. You are effectively echo-ing the literal string /sys/bus/hid/drivers/hid-multitouch (if ls finds the file at that path) over to the pipe and awk just writes that to the /sys/bus/hid/drivers/hid-multitouch/unbind file which might not be your desired action. You just needed to do run the command on the file directly as
      awk 'NR == 1 { print $1 }' /sys/bus/hid/drivers/hid-multitouch > /sys/bus/hid/drivers/hid-multitouch/unbind
      
    3. Now that, that the awk command is fixed, you have two options to run the above command as part of systemd, either put your command in a script or run the command directly. For putting it in a script refer to the Unix.SE answer Where do I put scripts executed by systemd units?. As for running the command directly in ExecStart. Aside from using /bin/sh also use the path /bin/awk

    So putting it together and using /bin/ over /usr/bin, you can do below. This command uses ".." over awk script and needs escape of $1

    ExecStart=/bin/sh -c '/bin/awk "NR == 1 { print \$1 }" /sys/bus/hid/drivers/hid-multitouch > /sys/bus/hid/drivers/hid-multitouch/unbind'