93

I'm trying to set up a simple systemd timer to run a bash script every day at midnight.

systemctl --user status backup.service fails and logs the following:

backup.service: Failed at step EXEC spawning /home/user/.scripts/backup.sh: No such file or directory.

backup.service: Main process exited, code=exited, status=203/EXEC
Failed to start backup.
backup.service: Unit entered failed state.
backup.service: Failed with result 'exit-code'.

I'm lost, since the files and directories exist. The script is executable and, just to check, I've even set permissions to 777.

Some background:

The backup.timer and backup.service unit files are located in /home/user/.config/systemd/user.

backup.timer is loaded and active, and currently waiting for midnight.

Here's what it looks like:

[Unit]
Description=Runs backup at 0000

[Timer]
OnCalendar=daily
Unit=backup.service

[Install]
WantedBy=multi-user.target

Here's backup.service:

[Unit]
Description=backup

[Service]
Type=oneshot
ExecStart=/home/user/.scripts/backup.sh

[Install]
WantedBy=multi-user.target

And lastly, this is a paraphrase of backup.sh:

#!/usr/env/bin bash

rsync -a --delete --quiet /home/user/directory/ /mnt/drive/directory-backup/

The script runs fine if I execute it myself.

Not sure if it matters, but I use fish as my shell (started from .bashrc).

I'm happy to post the full script if that's helpful.

8
  • 4
    What does ls -l /home/user/.scripts/backup.sh output ? The start of your backup.sh script looks very strange: #!/user/env/bin bash , does the executable /user/env/bin actually exist ? Are you sure you didn't mean /usr/bin/env or /home/user/bin/env ?
    – nos
    Commented Aug 19, 2017 at 21:07
  • ls outputs -rwxrwxrwx 1 dwrz dwrz 1470 Aug 11 01:57 /home/user/.scripts/backup.sh. And my apologies -- the typo in the shebang was when I was copying things over to here. It's /usr/ in the script.
    – dwrz
    Commented Aug 19, 2017 at 23:36
  • Aside: Starting fish from .bashrc is a really bad idea. Update your /etc/passwd entry to directly specify fish, don't confuse programs that may intentionally want to run an interactive bash instance by making it start a different, incompatible shell instead. Commented Aug 19, 2017 at 23:41
  • As for the immediate issue at hand, I'd start by reproducing it with Sysdig tracing execution; that way you can find the exact syscall that fails and extract pertinent details (active PATH, uid, gid, etc). Commented Aug 19, 2017 at 23:43
  • BTW, is there a PATH set when your service is invoked? If env bash can't find bash because there's no PATH, that would cause your bug. Setting Environment=PATH=/bin:/usr/bin or otherwise a known-good value in the .service wouldn't hurt. Commented Aug 19, 2017 at 23:44

8 Answers 8

213

I think I found the answer:

In the .service file, I needed to add /bin/bash before the path to the script.

For example, for backup.service:

ExecStart=/bin/bash /home/user/.scripts/backup.sh

As opposed to:

ExecStart=/home/user/.scripts/backup.sh

I'm not sure why. Perhaps fish. On the other hand, I have another script running for my email, and the service file seems to run fine without /bin/bash. It does use default.target instead multi-user.target, though.

Most of the tutorials I came across don't prepend /bin/bash, but I then saw this SO answer which had it, and figured it was worth a try.

The service file executes the script, and the timer is listed in systemctl --user list-timers, so hopefully this will work.

Update: I can confirm that everything is working now.

12
  • 13
    This solved it for me. The reason it works with other scripts is that they have a shebang (#!/bin/bash) at the beginning while this particular one had not. Commented Apr 5, 2018 at 15:17
  • 1
    Even when the executable is not a bash script, such as in my case, jupyter on CentOS 7, /bin/bash -c "..." is necessary. I think it is because it's a python script, and it has a shebang of python at the very beginning.
    – WesternGun
    Commented May 31, 2018 at 9:01
  • 1
    Scripts should have an interpreter, otherwise they're not a script. You should fix the script, rather than add bash to your .service file. Commented Dec 6, 2018 at 13:37
  • 1
    Sometimes you need a chmod +x /home/user/.scripts/backup.sh.
    – ST-DDT
    Commented Feb 21, 2019 at 14:01
  • 1
    In my case I was missing .sh extension
    – nilesh
    Commented May 6, 2019 at 18:57
20

To simplify, make sure to add a hash bang to the top of your ExecStart script, i.e.

#!/bin/bash

python -u alwayson.py    
0
10

When this happened to me it was because my script had DOS line endings, which always messes up the shebang line at the top of the script. I changed it to Unix line endings and it worked.

1
  • 3
    You saved my life! I just added #!/usr/bin/env bash at the first line of the .sh then worked.
    – kujiy
    Commented Apr 23, 2018 at 2:11
10

I ran across a Main process exited, code=exited, status=203/EXEC today as well and my bug was that I forgot to add the executable bit to the file.

1
  • 1
    I came here and read the marked answer and discovered before reading your answer that simply doing a chmod 700 <script> resolved my issue. This should be marked as the correct answer. I did not have to add /bin/bash <script-start> as the marked answer states. Commented Nov 5, 2020 at 0:50
9

If that is a copy/paste from your script, you've permuted this line:

#!/usr/env/bin bash

There's no #!/usr/env/bin, you meant #!/usr/bin/env.

1
  • 1
    Nice catch! The script is correct now, but it's possible I may have fixed it afterwards. It if it was a copy-paste, this would have explained it.
    – dwrz
    Commented Mar 19, 2019 at 0:17
3

try running:

systemctl daemon-reload

and then again run

service <yourservice> status
1

I faced a similar issue, changed the permission and added executable permission

use chmod +x /etc/systemd/system/<service-filename>

This worked for me

0

I actually used the answer from How do I run a node.js app as a background service? combined with what dwrz said above. In my case, I was creating a Discord bot that needed to be able to run when I was not around.

With this service in place, I initially got the same error that the initial poster did, which brought me here. I was missing the #!/usr/bin/env node at the top of my executed node.js script.

Since then, no problems, although I intend to see what else can be extended to the service itself.

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