this post was submitted on 29 Mar 2025
14 points (100.0% liked)

Linux

6786 readers
179 users here now

A community for everything relating to the GNU/Linux operating system

Also check out:

Original icon base courtesy of [email protected] and The GIMP

founded 2 years ago
MODERATORS
14
submitted 2 days ago* (last edited 1 day ago) by [email protected] to c/[email protected]
 

SOLVED If any lost souls find themselves here in a similar situation let it be known that the file that worked for me was creating a file at '%h/.config/systemd/user/google-drive-ocamlfuse.service' with the following content:

[Unit]
Description=FUSE filesystem over Google Drive
After=network.target

[Service]
ExecStart=google-drive-ocamlfuse %h/googledrive
ExecStop=fusemount -u %h/googledrive
Restart=always
RestartSec=300
Type=forking

[Install]
WantedBy=default.target

Howdy, I have very recently installed Opensuse Tumbleweed alongside Windows 10 (On a seperate drive) and am trying to get things setup to where I can fully transition to linux. One of the first things I have hit a wall on is getting a file to execute on boot using systemd.

I am trying to use this package to be able to access my google drive from Dolphin. And so far it works okay. Except that it doesn't survive a reboot. I have to run the command:

google-drive-ocamlfuse ~/googledrive

after each reboot in order for the google drive directories to be accessible. So I googled how to make that happen automagically on boot and found this guide that helped me get a startup script going.

I created /usr/local/bin/ocamlfuseStartup.sh as a file that contains the command from before:

google-drive-ocamlfuse ~/googledrive

and verified that it works as intended when I enter ./ocamlfuseStartup.sh from that directory.

I then created another file at /usr/lib/systemd/system/startup.service that contains the following:

[Unit]
Description=Startup Script

[Service]
ExecStart=/bin/bash /usr/local/bin/ocamlfuseStartup.sh

[Install]
WantedBy=multi-user.target

I have no idea what the /bin/bash portion is for because I found it from a googling but without it I get the following error:

startup.service: Main process exited, code=exited, status=203/EXEC

However with it I get this error:

startup.service: Main process exited, code=exited, status=2/INVALIDARGUMENT

which I take to mean that there is something wrong with my ocamlfuseStartup.sh file maybe? But since it works when I manually execute the file I'm kind of at a loss.

I found this thread where it seemed like someone else was having a similar issue but I didn't really grok what they were talking about.

Any and all help is greatly appreciated!

all 22 comments
sorted by: hot top controversial new old
[–] [email protected] 15 points 2 days ago* (last edited 2 days ago) (2 children)

The 203 error you got is because your script isnt a valid executable, it needs to have a shebang at the top, you can change it to something like this and set the executable bit with chmod +x <file>

#!/usr/bin/env bash
google-drive-ocamlfuse ~/googledrive

this tells it to run using bash as the interpreter.

Im not familliar with this google drive software, but im figuring that its exiting with an error code cuz its running as a system service, and $HOME probobly isnt set so ~ doesnt expand and the software gets an invalid path.

But I recommend using a user service for this, it will run when you login, you should be able to copy the service file you already have into ~/.config/systemd/user/ and run systemctl --user daemon-reload and systemctl --user enable startup.service --now, this will enable and start the service in one go.

I also recommend adding the following lines under [Service]

Type=simple
Restart=always
RestartSec=60

idk if the software will exit if it loses network or wifi or anything, but this will have it automatically restart after 60 seconds, should it exit for any reason.

If you need it to run before login, it is possible to do with a system service, but it will need a bit more setup

[–] [email protected] 4 points 2 days ago (1 children)

Thanks a ton for your help! I'm not quite there but I feel like I'm learning more lol

With your help I have made the changes you listed as well as some other changes while trying to troubleshoot. In no particular order:

Moved ocamlfuseStartup.sh to ~/.local/bin/ocamlfuseStartup.sh because I now am more familiar with what an immutable distro is and does and also added the shebang. File now reads:

#!/usr/bin/env bash
/usr/bin/google-drive-ocamlfuse ~/googledrive

Moved startup.service to ~/home/tyler/.config/systemd/user/startup.service, file now reads as follows:

[Unit]
Description=Startup Script

[Service]
Type=simple
Restart=always
RestartSec=60
ExecStart=/bin/bash ~/.local/bin/ocamlfuseStartup.sh


[Install]
WantedBy=default.target

I am now getting (code=exited, status=127) when I run "systemctl --user status startup.service --now." Which I have googled and determined that it is now having difficulty finding the program or one of the dependencies according to the bash man page. I attempted to troubleshoot this error by adding the full location of the program /usr/bin/google-drive-ocamlfuse to the ocamlfuseStartup.sh file. I'm unsure how to proceed from here though. Once again, super appreciative of your help. I'm going to bed now though...

[–] [email protected] 4 points 2 days ago (1 children)

I dont think systemd will expand the ~, try replacing the ExecStart=/bin/bash ~/.local/bin/ocamlfuseStartup.sh line with ExecStart=/bin/bash %h/.local/bin/ocamlfuseStartup.sh, this will expand to your home directory, if its still giving a not found error, try running which google-drive-ocamlfuse in a terminal and make sure the path is correct

[–] [email protected] 1 points 2 days ago (1 children)

I really appreciate your help with this. With your changes we have even acheived some partial success!

I did verify the package location with which google-drive-ocamlfuse, and replaced the ~ with %h.

The current configuration for ocamlfuseStartup.sh is:

#!/usr/bin/env bash
/usr/bin/google-drive-ocamlfuse /home/tyler/googledrive

startup.service is now:

spoiler

[Unit]
Description=Startup Script

[Service]
Type=simple
Restart=always
RestartSec=60
ExecStart=/bin/bash %h/.local/bin/ocamlfuseStartup.sh


[Install]
WantedBy=default.target

This current configuration leads to 0=SUCCESS, and boy howdy was I ELATED! Until... I realized that it didn't actually do the thing... The directory %h/googledrive remains empty unless I manually run the command "google-drive-ocamlfuse ~/googledrive" as before.

Interestingly enough, status shows all good in the hood as far as I can tell:

spoiler

~> systemctl --user status startup.service --now
● startup.service - Startup Script
     Loaded: loaded (/home/tyler/.config/systemd/user/startup.service; enabled; preset: disabled)
     Active: activating (auto-restart) since Sat 2025-03-29 15:37:04 CDT; 58s ago
 Invocation: 96b64438a1be4e36a12018e86418d8c6
    Process: 3822 ExecStart=/bin/bash /home/tyler/.local/bin/ocamlfuseStartup.sh (code=exited, status=0/SUCCESS)
   Main PID: 3822 (code=exited, status=0/SUCCESS)
        CPU: 49ms

journalctl also shows no whammies as far as I can tell:

spoiler

~> journalctl --user -xeu google-drive-ocamlfuse.service
Mar 29 15:33:54 DESKTOP-MDJUBMM.attlocal.net systemd[1716]: Started FUSE filesystem over Google Drive.
░░ Subject: A start job for unit UNIT has finished successfully
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░ 
░░ A start job for unit UNIT has finished successfully.
░░ 
░░ The job identifier is 704.
Mar 29 15:38:56 DESKTOP-MDJUBMM.attlocal.net systemd[1716]: google-drive-ocamlfuse.service: Scheduled restart job, restart counter is at 2.
░░ Subject: Automatic restarting of a unit has been scheduled
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░ 
░░ Automatic restarting of the unit UNIT has been scheduled, as the result for
░░ the configured Restart= setting for the unit.
Mar 29 15:38:56 DESKTOP-MDJUBMM.attlocal.net systemd[1716]: Started FUSE filesystem over Google Drive.
░░ Subject: A start job for unit UNIT has finished successfully
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░ 
░░ A start job for unit UNIT has finished successfully.
░░ 
░░ The job identifier is 806.
lines 16-38/38 (END)

So I am once again stumped. I feel like it's so close.

However, with resources from others in this thread I have begun a war on two fronts. Introducing our newest contender ~/.config/systemd/user/google-drive-ocamlfuse.service Which as far as I can tell is another way of skinning this cat that doesn't involve a seperate .sh file to be called. Seems cleaner than the angle I had started working from, but what do I know. Special thanks to Oscar with his github link to documentation and after some iterative monkeying google-drive-ocamlfuse.service looks like so:

spoiler

[Unit]
Description=FUSE filesystem over Google Drive
After=network.target

[Service]
ExecStart=google-drive-ocamlfuse /home/tyler/googledrive
Restart=always
RestartSec=300
Type=simple

[Install]
WantedBy=default.target

And again 0=SUCCESS and premature elation, but alas no joy. Remarkably similar status and journalctl entries, so I remain stumped. Or possibly double stumped...

spoiler

~> systemctl --user status google-drive-ocamlfuse.service --now
● google-drive-ocamlfuse.service - FUSE filesystem over Google Drive
     Loaded: loaded (/home/tyler/.config/systemd/user/google-drive-ocamlfuse.service; enabled; preset: disabled)
     Active: activating (auto-restart) since Sat 2025-03-29 15:49:00 CDT; 1min 5s ago
 Invocation: 813f1d3ce9fd4c21b409074a9fca7776
    Process: 4271 ExecStart=google-drive-ocamlfuse /home/tyler/googledrive (code=exited, status=0/SUCCESS)
   Main PID: 4271 (code=exited, status=0/SUCCESS)
        CPU: 42ms
~> journalctl --user -xeu google-drive-ocamlfuse.service
Mar 29 15:43:57 DESKTOP-MDJUBMM.attlocal.net systemd[1716]: Started FUSE filesystem over Google Drive.
░░ Subject: A start job for unit UNIT has finished successfully
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░ 
░░ A start job for unit UNIT has finished successfully.
░░ 
░░ The job identifier is 908.
Mar 29 15:48:58 DESKTOP-MDJUBMM.attlocal.net systemd[1716]: google-drive-ocamlfuse.service: Scheduled restart job, restart counter is at>
░░ Subject: Automatic restarting of a unit has been scheduled
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░ 
░░ Automatic restarting of the unit UNIT has been scheduled, as the result for
░░ the configured Restart= setting for the unit.
Mar 29 15:48:58 DESKTOP-MDJUBMM.attlocal.net systemd[1716]: Started FUSE filesystem over Google Drive.
░░ Subject: A start job for unit UNIT has finished successfully
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░ 
░░ A start job for unit UNIT has finished successfully.
░░ 
░░ The job identifier is 1031.
lines 46-68/68 (END)

I have attempted to run these competing services seperately as well as in tandem with the same lack of results. I feel that if I can't get it licked soon I will kick systemd to the curb and attempt another method outlined in the github link provided by Oscar. Most likely the fstab method that he mentioned because it sounds violent and that's the vibe at the moment lol. Once again thank you for any and all assistance.

[–] [email protected] 2 points 2 days ago (1 children)

It looks like its creating a new process and going in the background and systemd cant track it anymore, so it thinks that its exited and tries restarting. I took a link Oscar sent, and I saw that there is a systemd service and the Type is set to forking, I think this could solve the problem, they also have an ExecStop line, id set it to ExecStop=fusermount -u %h/googledrive so it will unmount properly whenever you manually stop the service. So try setting Type=forking, and adding the ExecStop line, hopefully this will stop systemd from restarting it when it hasnt actually exited

[–] [email protected] 1 points 1 day ago

HOLY SHIT WE DID IT!!! I have now rebooted several times and the changes you recommended have made it work automagically! I'm so relieved! I can't thank you enough, and I definitely owe you a beer.

[–] [email protected] 3 points 2 days ago* (last edited 2 days ago) (1 children)

They could use loginctl enable-persist if they want a user service to run at boot. I use it for my home nas server, just to make it slightly easier to manage my non-root services.

[–] [email protected] 1 points 2 days ago

Thanks for your input, I'll look into this.

[–] [email protected] 4 points 2 days ago (1 children)

I would just throw google-drive-ocamlfuse ~/googledrive in your .profile, but if you want to use systemd:

[Unit]
Description=Google drive fuse mount
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=<USER>
ExecStart=/usr/bin/google-drive-ocamlfuse /home/<USER>/googledrive
ExecStop=/usr/bin/google-drive-ocamlfuse -u /home/<USER>/googledrive

[Install]
WantedBy=multi-user.target
[–] [email protected] 2 points 2 days ago

Thanks for your input! I've gone down the systemd rabbit hole far enough to be somewhat committed to making it work. But certainly willing to try other methods. I'm enjoying learning more about linux but at the same time I really just need the shit to work though lol

[–] [email protected] 2 points 2 days ago (2 children)

I had an idea of trying to use fstab to make it mount the same way as any other drive, which lead me to this page:

https://github.com/astrada/google-drive-ocamlfuse/wiki/Automounting#mount-using-fstab

Hopefully you can find some clues in there.

[–] [email protected] 2 points 2 days ago

Thanks a ton my dude! This link has been very helpful. I feel like I'm very close! If I can't get systemd licked I'm definitely going to fstab my computer lol Thanks again for the help, friend!

[–] [email protected] 2 points 2 days ago

Oh, and further down, there's a way with systemd instead.

[–] [email protected] 2 points 2 days ago* (last edited 2 days ago) (1 children)

i would install cron if its not installed, then add a file under

/etc/cron.d/someNiceToRememberName

and with an editor write the following in it:

@reboot root /bin/bash -x /usr/local/bin/ocamlfuseStartup.sh >> /tmp/output 2>&1 ; echo returncode=$? >> /tmp/output

where root is the user it should run with and the redirection (>> /tmp/output 2>&1) is for seeing what is wrong, and echo returncode= prints the exit error indicator.

you might be able to do this with systemd too, but it often messes things up and i like i.e. clean log outputs.

for testing you can add a line that would start it without a reboot.

22 * * * * root /path/to/your/command parameters >> /tmp/output 2>&1

where the 22 is the next minute it should run. with this cronjob it would be run at every x:22 after each hour 09:22 pm 10:22 pm aso. i do this sometimes for testing

as systemd starts cron with a broken environment too, it might as well not work using cron, but then you know its the broken environment systemd starts it with. if thats your problem, you might want to add: PATH=$PATH:/usr/sbin:/usr/local/sbin

somewhere at the top of the shellscript depending on what is missing, which by itself would be the directories the commands executed are in. in terminal use :

$ which sed
/sbin/sed

for example to find where the "sed" binary is located (if the script cannot find it) you could change every occurance of "sed" in the script with the full path to it, or add the directory using the PATH variable as a colon separated list of directories to search commands in (where order matters)

to maybe more easy see what is missing i added the -x as a parameter to bash which makes it print out a line for every command it executes to sdterr so you can see what the last commands were. you can try it in the terminal (if your terminal is bash or compatible

$ set -x
$ echo foo
+ echo foo
foo
$ 

i'ld guess systemd starts the shellscript with a broken environment and thats maybe why it doesnt work, maybe try adding this to the script too:

echo PATH: $PATH

somewhere at the top of the script and use the redirection i showed for the cron job. run it once in your terminal and compare the output with what it prints during automated script run.

good luck.

transition to linux. One of the first things I have hit a wall on is getting a file to execute on boot using systemd.

I am trying to use this package to be

that bash thing is the interpreter. the script ocamlFuseStartup.sh is written as bash (possibly the same as your terminal) if that script has a "shebang" (#!/bin/bash) as the very first line AND the file has the execute permission set (chmod +x /path/to/file), then you dont need /bin/bash at the beginning to start it.

[–] [email protected] 1 points 2 days ago (1 children)

I like to have a decently firm grasp of the commands I type into the terminal so either I'm too high or what you're throwing down is more advanced than I'm comfortable with. Thank you for your help though. Especially regarding the broken environment, I think I am dealing with some of that now as I am now receiving an error 127. I added the full path for the google-drive-ocamlfuse package but am still receiving the error 127 so I will try to load it's dependencies next time similar to your which sed example.

[–] [email protected] 2 points 2 days ago

not sure at what level you are, here are some hints:

take your time to understand what the things do. shells like bash are very powerful and accidentially typing simething wrong could cause data loss or similar. but as you said, take care that you undestand what things are for and how they work.

most tools like sed or bash have a manpage that helps. bash has a huge one as it is very powerull (want to "program" like in C with pointers to variables, bash can do so using eval, which is evil, it really has downsides when doing too much in bash), but anyway learn the tools you use as you try them.

man sed
man bash

you can leave the manpage with pressing "q". pressing "h" shows how to navigate man pages.

the exit code of your script could come from bash itself or from the last command executed, it depends a bit. lets say bash stumbles over invalid syntax in the script while running the code or over a redirection ('<' '>') that points to an empty variable or nonexisting directory, then its bash who exits with its error. so an empty variable could cause such an error. but it usually exits with the exit code of the last run command (see bash "set -e" option which lets bash exit on the first failed command which together with the "-x" switch is very handy, but dont confuse it with other "-e" things in bash's huge manpage)

try in your console:

$ ( exit 34 )
$ echo $?
34

$ /bin/false
$ echo $?
1

$ ( set -e ; /bin/false ; echo bar )
$ echo $?
1

$ ( /bin/false ; echo foo )
foo
$ echo $?
0

using () in a terminal opens a subshell so that what you do there (set -e, setting variables etc) does not affect your current shells environment (unless you change files on disk or such) in the last case the exit code was from the "echo foo" command which succeded and returned 0 while the exit code of /bin/false was ignored (other than in that 'set -e' example)

i use exit codes a lot in bash scripts to control script flow also together with functions.

some programs have a bit mask of what went wrong ('man fsck' explains that they use a bitwise OR to determine the resulting exit code of the program to include multiple possible errors at once) so when dealing with an exit code other than 0 you likely first want to know which program caused it (maybe using the "-x" switch i.e.) and then consult man page or online help what it means.

as ocamlfuseStartup.sh is a shellscript you likely find what happens inside of it.

good luck