How to write startup script for Systemd?

I have 2 graphics cards on my laptop. One is IGP and another discrete.

I’ve written a shell script to to turn off the discrete graphics card.

How can I convert it to systemd script to run it at start-up?

Asked By: Sharique

||

There are mainly two approaches to do that:

With script

If you have to run a script, you don’t convert it but rather run the script via a systemd service:

Therefore you need two files: the script and the .service file (unit configuration file).
Make sure your script is executable and the first line (the shebang) is #!/bin/sh. Then create the .service file in /etc/systemd/system (a plain text file, let’s call it vgaoff.service).
For example:

  1. the script: /usr/bin/vgaoff
  2. the unit file: /etc/systemd/system/vgaoff.service

Now, edit the unit file. Its content depends on how your script works:

If vgaoff just powers off the gpu, e.g.:

exec blah-blah pwrOFF etc 

then the content of vgaoff.service should be:

[Unit]
Description=Power-off gpu

[Service]
Type=oneshot
ExecStart=/usr/bin/vgaoff

[Install]
WantedBy=multi-user.target

If vgaoff is used to power off the GPU and also to power it back on, e.g.:

start() {
  exec blah-blah pwrOFF etc
}

stop() {
  exec blah-blah pwrON etc
}

case $1 in
  start|stop) "$1" ;;
esac

then the content of vgaoff.service should be:

[Unit]
Description=Power-off gpu

[Service]
Type=oneshot
ExecStart=/usr/bin/vgaoff start
ExecStop=/usr/bin/vgaoff stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Without script

For the most trivial cases, you can do without the script and execute a certain command directly:

To power off:

[Unit]
Description=Power-off gpu

[Service]
Type=oneshot
ExecStart=/bin/sh -c "echo OFF > /whatever/vga_pwr_gadget/switch"

[Install]
WantedBy=multi-user.target

To power off and on:

[Unit]
Description=Power-off gpu

[Service]
Type=oneshot
ExecStart=/bin/sh -c "echo OFF > /whatever/vga_pwr_gadget/switch"
ExecStop=/bin/sh -c "echo ON > /whatever/vga_pwr_gadget/switch"
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Enable the service

Once you’re done with the files, enable the service:

systemctl enable vgaoff.service

It will start automatically on next boot. You could even enable and start the service in one go with

systemctl enable --now vgaoff.service

as of systemd v.220 (on older setups you’ll have to start it manually).
For more details see systemd.service manual page.

Troubleshooting

Answered By: don_crissti

Adding startup items in systemd is complex and cumbersome. To make this more convenient, I have wirte a tool add_service which provides a simple way to quickly add startup item in systemd.

Install:

pip3 install add_service

Usage:

python -m add_service [shell_file/cmd] [user (default `whoami`)]

Examples:

python -m add_service ssh_nat.sh  # by default user is `whoami`
python -m add_service "`which python3` -m http.server 80" root
Answered By: Yang
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.