8

I have custom script to mount google drives.
Part of this script, is following code:

if [ ! "$(which google-drive-ocamlfuse)" ]
then
    echo "Install google-drive-ocamlfuse first!"
    exit 1
fi

Executed from terminal, works like charm.
So, I configured it as service:

[Unit]
Description=Mount and umount google drives

[Service]
User=<usernamehere>
Type=oneshot
RemainAfterExit=true
ExecStart=/home/<usernamehere>/mybscripts/gdrivemounter.sh -m
ExecStop=/home/<usernamehere>/mybscripts/gdrivemounter.sh -u
Environment="DISPLAY=:0"
Environment="XAUTHORITY=/home/<usernamehere>/.Xauthority"

[Install]
WantedBy=graphical.target

Unfortunately, I see exit code: "Install google-drive-ocamlfuse first!" when I checking service status.

Command which google-drive-ocamlfuse under user and root gives me valid path:

$ which google-drive-ocamlfuse
/home/<usernamehere>/.opam/default/bin/google-drive-ocamlfuse

Where is the problem?

  • I don't know how your service files are configured but I suspect that the description needs to be in quotes? Description="Mount and umount google drives" maybe – djsmiley2kStaysInside Sep 28 '19 at 12:21
  • Checking the redhat documentation it seems that isn't the case. And re-reading your question it can't be the issue as the script is being executed. I'm presuming for 'user' you have it set to run as your own user? If not, you need to check that the user you're running it as, has access to google-drive-ocamlfuse. This may require making sure it's on their $PATH which might be different to the $PATH you have when you login on an interactive shell. – djsmiley2kStaysInside Sep 28 '19 at 12:23
  • @djsmiley2k what is important: without code in first block, script working as service perfectly. – rah606 Sep 28 '19 at 12:26
  • 1
    That's very weird, can you add echo $PATH to the error block, to see what path is set to at that time. – djsmiley2kStaysInside Sep 28 '19 at 12:28
  • 1
    As a side note, this should probably run as user systemd instance. It will assume environment of your user by default. Put it in ~/.config/systemd/user/ and run with systemctl --user start <service>. (Note: I believe not all distributions enable user systemd instance by default) – Mirek Długosz Sep 29 '19 at 9:10
12

The problem is that, when the script runs as a service, it does not run as "you": it does not have your environment. Specifically, it does not have your PATH variable.

Either add /home/<usernamehere>/.opam/default/bin to the PATH in your script, or simply hardcode the full path for that program.

| improve this answer | |
  • While I think this is the issue, it'd be better to add the path via the service file using environment, as this way it'll only modify $PATH while running the service. Your way will modify it for any user running the script, and make the check entirely pointless. – djsmiley2kStaysInside Sep 28 '19 at 12:31
  • 1
    IMO the check is already not very valuable. Just set up the PATH and execute the program. If it's not there, bash will give you a descriptive error message. I would be surprised if there are other users on the OP's system (this is exactly the kind of script I've written on my own laptop). – glenn jackman Sep 28 '19 at 12:34
3

The most likely reason is that the directory containing google-drive-ocamlfuse is in the PATH of your login shell, but not in the standard PATH used by systemd.

Just add a line like this at the beginning of your script:

PATH=$PATH:/path/to/google-drive-ocamlfuse
| improve this answer | |
  • While I think this is the issue, it'd be better to add the path via the service file using environment, as this way it'll only modify $PATH while running the service. Your way will modify it for any user running the script, and make the check entirely pointless. – djsmiley2kStaysInside Sep 28 '19 at 12:30
  • You assume the point is to test whether the program in the current PATH. More likely the point is to find out whether the program is present or not. – RalfFriedl Sep 28 '19 at 12:35
  • You presume the script is running on a single user system. Adding a $PATH to another users' home directory isn't going to go well for you if anyone else needs to run this script. – djsmiley2kStaysInside Sep 28 '19 at 12:37
  • I noticed that the script as already in some user`s home directory, so it is probably not intended to be executed by other users. – RalfFriedl Sep 28 '19 at 12:43
1

Thank you all for solutions. Each is important for me and helpful - again I learned something new. At the end I decided to install google-drive-ocamlfuse from deb, instead via opam. It is better to install gdo in path available for all users. Due to this, additional configuration of $PATH is not necessary.

| improve this answer | |
  • I'm still wondering, did configuring the $PATH by which ever method you choose, fix the issue? If so, and the script is being ran as your user, that's a very interesting finding. – djsmiley2kStaysInside Sep 29 '19 at 12:42
  • Generally use the system package manager to install things unless you have very good reason to do it another way. This mean that the maintenance burden moves from you to the operating system maintainers, so you can do something else. – Thorbjørn Ravn Andersen Sep 29 '19 at 17:05
1

Note: I've left this answer 'as is' but the only relevant part is how to set the environment via the service file, rather than directly in the script. Setting a new $PATH in the script won't persist after the script has finished running.

In reference to the other answers, please don't pollute your $PATH by editing your script, when in fact it works if ran by the correct user. If you must edit it directly in the script, put it back after by restoring the original $PATH.

I think the issue lies with the fact that /etc/profile isn't processed by systemd services, and so it hasn't for whatever reason got access (or an updated $PATH) for the executable required.

To test this you could echo out $PATH within the error block, and if it IS missing, then add it directly into the Environment variable within the systemd service file:

[Service]
Environment=PATH=/home/someUser/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

This way, the path is only updated for the script while it runs, it doesn't modify it for users who might not expect it to be modified..

| improve this answer | |
  • 3
    Environment is per-process – any changes done within the script will be lost once the script exits, so "putting it back" is completely redundant. – user1686 Sep 28 '19 at 13:26
  • Ah I was thinking of export... – djsmiley2kStaysInside Sep 28 '19 at 14:33
  • 1
    Still applies even to export. Child processes of that script (or interactive shell) will inherit the exported environment variables; all other processes will not see the changes at all. – user1686 Sep 28 '19 at 16:52
  • @grawity yeah, I read that too now, I guess my answer is not really adding anything useful other than maybe the systemd file change. I'll add a a comment to the answer to indicate so, thanks for helping me learn :) – djsmiley2kStaysInside Sep 29 '19 at 12:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.