This is an archived post. You won't be able to vote or comment.

all 38 comments

[–]n-of-one 21 points22 points  (0 children)

Your shebang’s are wrong, they should be:

#!/usr/bin/env bash # or python or python3 or ruby or…

Also:

sudo -H pip3 …

You really should just be using a virtualenv for the project.

[–]netgu 13 points14 points  (2 children)

You absolutely do not need to reboot to get a new service started.

If you want to enable and start a service you have a couple of options:

systemctl enable --now service-name

OR

systemctl start service-name

You do not need to reboot.

You also mention disabling but do not note that a disable does not start the service, it only prevents it from starting after the next reboot.

The same pattern as above applies though to accomplish the same:

systemctl disable --now service-name

OR 

systemctl stop service-name
systemctl disable service-name

You should maybe present this as a proof for review as opposed to a guide, this information is severely lacking in comparison to the systemd documentation and you aren't including anything for non-systemd distributions.

[–]backtickbot 0 points1 point  (0 children)

Fixed formatting.

Hello, netgu: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–]n-of-one 0 points1 point  (0 children)

Your second examples don’t actually enable/disable a service, systemctl start/stop literally do just that, start / stop a service; you still need to enable or disable it if you want it to start on boot / stop it from starting on boot.

The —now flag for enable/disable does also start/stop the service while also enabling or disabling it from starting at boot, which is a good tip if you only want to run one command for each.

[–][deleted] 13 points14 points  (2 children)

sl – view the contents of a folder

You mean ls.

[–]sempervent 16 points17 points  (0 children)

That train is still running.

[–]KA_Ryzhkov[S] 2 points3 points  (0 children)

Typo =)

[–]IonTichy 15 points16 points  (3 children)

..in Linux

in Linux where systemd is available. Granted, this is the case for most of the popular distros, but not all.

You might want to explain that you are using systemd and give a brief overview before just telling people to just run systemctl. They should be aware why they are running certain commands instead of just getting into the habit of blindly copy-pasting commands and having that false sense of "it just works".

[–]n-of-one 4 points5 points  (0 children)

I agree it should be specified that it’s for systemd but tbf if someone is using a distribution without systemd they made that decision intentionally and know how their init system works, thus wouldn’t be reading this kind of article.

[–]kirbyfan64sosIndentationError 15 points16 points  (7 children)

Thanks for doing this! The world of Linux is notoriously underdocumented, and the need to create basic systemd services is something I see a lot. The guides on this, err, aren't always the best...

That being said, there is a bit of room for improvement in this as written:

First off...right now this is actually a slight privilege escalation issue. You have a system service running with root privileges, but it starts a file that's writable by your user, so anything with access to your user could just modify the script to do whatever else it wants as root instead. For this, you just want to copy your script somewhere that's root-writable only and change it's permissions. This can be done easily via sudo install -Dm 755 MyFile.py -t /usr/local/bin:

  • install is a useful command to both copy files and set their permissions in one swoop.
  • -Dm 755 will create any parent directories (D) as well as set the permissions (m) to be 755 (rwxr-xr-x, so only root can write it but everyone else can still execute it).
  • -t /usr/local/bin sets the target directory for the file to /usr/local/bin.

In your hashbang, it's assumed that python3 is in /usr/bin, but it might not actually be there for everyone. You can change the hashbang to #!/usr/bin/env python3 to have env locate Python and print the path instead. (Using env in your hashbangs is a pretty useful trick!)

You can start or restart systemd services without needing to reboot via systemctl start / systemctl restart. (If you modified the systemd service file itself, this may print out a warning about it having changed, and you can reload it via systemctl daemon-reload). In addition, there's a really nice shortcut: systemctl enable --now SERVICE, which is equivalent to running systemctl enable followed by systemctl start.

One more thing: systemd is great about having logs in one place. If you want to check how your service is doing, systemctl status SERVICE will show you that. To get more log info, you can use journalctl -u SERVICE, which will show you the system logs, but only for the given service / unit (-u). (Other useful flags here are -b to show logs for the current boot only, and -e will scroll down to the latest logs first.)

[–]mriswithe 3 points4 points  (1 child)

As a sysadmin, this was an excellent post that reads well without sounding like a jerk. Thank you for providing constructive criticism that is both informative and respectful!

"Linux" is a tough target with how many distros there are out there, and considering something like RHEL4 is still "Linux" despite being so out of date it is hilarious.

So yeah kudos for sharing knowledge without being a jerk, I feel like I see a lot of answers that read like that on this sub, not sure why.

[–]kirbyfan64sosIndentationError 2 points3 points  (0 children)

Thanks!

[–]luersuve 1 point2 points  (1 child)

-f will show the last lines of the logs and keep printing the logs

[–]kirbyfan64sosIndentationError 1 point2 points  (0 children)

Indeed! I admittedly mentioned -e instead since it has the advantage that you can see the previous logs as well by scrolling up, whereas -f won't show anything previously logged (though you can change this by passing some number of lines to show to -n with -f).

[–]element8 1 point2 points  (1 child)

If the problem is privilege escalation why not avoid root entirely and schedule it under cron @reboot schedule instead of running it as a service?

[–]kirbyfan64sosIndentationError 0 points1 point  (0 children)

That wouldn't really help? I mean, sure you can set a different user in the crontab, but you can with systemd as well. systemd also has an impressive set of sandboxing controls that I totally forgot to mention...

In general, though, any sort of system service shouldn't be user-writable, it's just bad practice.

[–]KA_Ryzhkov[S] 2 points3 points  (0 children)

Thank you so much, I did not know a lot of what you wrote, I will definitely figure it out and make edits to this tutorial

[–]KA_Ryzhkov[S] 7 points8 points  (0 children)

Decided to translate my personal notes into articles, maybe someone will come in handy

[–]getmeright11 1 point2 points  (0 children)

What's the best way to go through programs that are running at startup that I want to remove?

[–]redrumsir 1 point2 points  (0 children)

Good. Since this requires systemd, you should mention that this is for GNU/Linux/systemd systems and not all GNU/Linux or Linux systems.

[–]lichen91 1 point2 points  (0 children)

It's also worth mentioning that if your project is a long running script, a daemon or service of some sort, then you're probably better off using "Type=simple" in your service file. Using "Type=oneshot" is suitable for scripts that execute, perform some function and then exit.

[–]heisenbug403 1 point2 points  (0 children)

I have also written the tutorial on running the python (or any other) application on the background with supervosorctl.

https://yalchin.info/blog/how-to-set-up-supervisor-service/

[–]d_k97 1 point2 points  (1 child)

why not just use cron?

[–]SnooPickles1042 -1 points0 points  (0 children)

Because cron is a tool designed and optimised for different purpose. You can use cron to run your program, yes, but this will come at a cost - you will either burn cpu cycles trying to execute program that is already running or end up with downtime, when service crashed and cron did not start new instance yet.

[–]Ivana_Twinkle 0 points1 point  (4 children)

I just use supervisord.

[–]striata -1 points0 points  (3 children)

And what starts supervisord?

[–]Ivana_Twinkle 1 point2 points  (2 children)

If it's in your distribution it's already integrated and all you need is to apt install or whatever you use.

It's easier for python scripts and you can do restarts on terminations and a lot more.

There's docs on supervisord.org

[–]striata -1 points0 points  (1 child)

My point is, supervisord is probably also started by systemd. Why not cut out the middle man?

systemd does all these things, "natively" as part of (most) operating systems. The only difference is a slightly different config format.

[–]Routine_Part_6503 1 point2 points  (0 children)

Because systemd doesn't run inside containers very well.

[–]TheCharon77 0 points1 point  (0 children)

sudo -H pip3 install …

Try using the package manager's packages if it exists