Systemd Service not executing bash script right

Hello dear Nix Wizards

I have a simple systemd service that is running a simple script:

systemd.services."ntfy-sh_notify-send" = {
  wantedBy = [ "default.target" ];
  partOf = [ "default.target" ];
  script = ''
#!/run/current-system/sw/bin/bash
/run/current-system/sw/bin/ntfy subscribe topic-bash '/run/current-system/sw/bin/notify-send "$m"'
  '';
};

when I trigger the script it get this error:

● ntfy-sh_notify-send.service
     Loaded: loaded (/etc/systemd/system/ntfy-sh_notify-send.service; enabled; preset: enabled)
     Active: active (running) since Mon 2023-08-14 19:21:41 CEST; 23min ago
   Main PID: 727 (ntfy-sh_notify-)
         IP: 12.3K in, 4.3K out
         IO: 18.8M read, 0B written
      Tasks: 8 (limit: 38435)
     Memory: 28.2M
        CPU: 108ms
     CGroup: /system.slice/ntfy-sh_notify-send.service
             ├─727 /nix/store/8fv91097mbh5049i9rglc73dx6kjg3qk-bash-5.2-p15/bin/bash /nix/store/3242ip1qiz7iaf3046jqh0zljh3596x1-unit-script-ntfy-sh_notify-send-start/bin/ntfy-sh_notify-send-start
             └─736 /run/current-system/sw/bin/ntfy subscribe topic-bash "/run/current-system/sw/bin/notify-send \"\$m\""

Aug 14 19:21:41 iMac systemd[1]: Started ntfy-sh_notify-send.service.
Aug 14 19:44:16 iMac ntfy-sh_notify-send-start[736]: 2023/08/14 19:44:16 WARN ntfy.sh/topic-bash/tPLIU7TPyIUZ Command failed: exec: "sh": executable file not found in $PATH
Aug 14 19:44:20 iMac ntfy-sh_notify-send-start[736]: 2023/08/14 19:44:20 WARN ntfy.sh/topic-bash/BUPYdYeA1pEE Command failed: exec: "sh": executable file not found in $PATH
Aug 14 19:44:47 iMac ntfy-sh_notify-send-start[736]: 2023/08/14 19:44:47 WARN ntfy.sh/topic-bash/4jXviXErN3Ux Command failed: exec: "sh": executable file not found in $PATH

The script on its own is working fine as an standalone bash script, so it must be something with the way NixOS is handling the script?

Would be great if someone has a hint to solve this!

Try this instead (not tested, sorry! The principle should be the same though):

systemd.services."ntfy-sh_notify-send" = {
  wantedBy = [ "default.target" ];
  partOf = [ "default.target" ];
  script = ''
    ${pkgs.ntfy}/bin/ntfy subscribe topic-bash '${pkgs.libnotify}/bin/notify-send "$m"'
  '';
  path = [pkgs.ntfy pkgs.libnotify];
};

If ntfy or notify-send depend on any other packages, you might have to add those to the path = statement as well.

2 Likes

hi firecat53, thank you for the good idea to a solution.

but now I get the following error:

× ntfy-sh_notify-send.service
     Loaded: loaded (/etc/systemd/system/ntfy-sh_notify-send.service; enabled; preset: enabled)
     Active: failed (Result: exit-code) since Tue 2023-08-15 07:05:29 CEST; 23s ago
   Duration: 208ms
    Process: 62505 ExecStart=/nix/store/f48kzjzr5x2sq5kr6686yf7xb347j0kz-unit-script-ntfy-sh_notify-send-start/bin/ntfy-sh_notify-send-start (code=exited, status=2)
   Main PID: 62505 (code=exited, status=2)
         IP: 0B in, 0B out
        CPU: 206ms

Aug 15 07:05:29 iMac systemd[1]: Started ntfy-sh_notify-send.service.
Aug 15 07:05:29 iMac ntfy-sh_notify-send-start[62506]: usage: ntfy [-h] [-c CONFIG] [-b BACKEND] [-o key value]
Aug 15 07:05:29 iMac ntfy-sh_notify-send-start[62506]:             [-l {CRITICAL,ERROR,WARNING,INFO,DEBUG}] [-v] [-q] [--version]
Aug 15 07:05:29 iMac ntfy-sh_notify-send-start[62506]:             [-E] [-t TITLE]
Aug 15 07:05:29 iMac ntfy-sh_notify-send-start[62506]:             {send,done,shell-integration} ...
Aug 15 07:05:29 iMac ntfy-sh_notify-send-start[62506]: ntfy: error: argument {send,done,shell-integration}: invalid choice: 'subscribe' (choose from 'send', 'done', 'shell-integration')
Aug 15 07:05:29 iMac systemd[1]: ntfy-sh_notify-send.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Aug 15 07:05:29 iMac systemd[1]: ntfy-sh_notify-send.service: Failed with result 'exit-code'.

As stated before the line works on it’s own when not in Nix systemd expression!

Heh…there’s two projects named ntfy. You’re trying to use the python one, but the golang one is the one apparently packaged in Nix.

Edit: try changing to path = [pkgs.ntfy-sh pkgs.libnotify];. That was prob my fault…didn’t realize there were two different ntfy’s!

2 Likes

Hey firecat53, I appreciate your help greatly! Thank you for that!

Good call with the wrong package!

I changed the script to path = [pkgs.ntfy-sh pkgs.libnotify]; but sadly still the same error:

× ntfy-sh_notify-send.service
     Loaded: loaded (/etc/systemd/system/ntfy-sh_notify-send.service; enabled; preset: enabled)
     Active: failed (Result: exit-code) since Tue 2023-08-15 19:13:42 CEST; 7s ago
   Duration: 229ms
    Process: 13315 ExecStart=/nix/store/b5q5i0ar9sr8as7a1jcf5i3ya20p8vy1-unit-script-ntfy-sh_notify-send-start/bin/ntfy-sh_notify-send-start (code=exited, status=2)
   Main PID: 13315 (code=exited, status=2)
         IP: 0B in, 0B out
        CPU: 225ms

Aug 15 19:13:42 iMac systemd[1]: Started ntfy-sh_notify-send.service.
Aug 15 19:13:42 iMac ntfy-sh_notify-send-start[13316]: usage: ntfy [-h] [-c CONFIG] [-b BACKEND] [-o key value]
Aug 15 19:13:42 iMac ntfy-sh_notify-send-start[13316]:             [-l {CRITICAL,ERROR,WARNING,INFO,DEBUG}] [-v] [-q] [--version]
Aug 15 19:13:42 iMac ntfy-sh_notify-send-start[13316]:             [-E] [-t TITLE]
Aug 15 19:13:42 iMac ntfy-sh_notify-send-start[13316]:             {send,done,shell-integration} ...
Aug 15 19:13:42 iMac ntfy-sh_notify-send-start[13316]: ntfy: error: argument {send,done,shell-integration}: invalid choice: 'subscribe' (choose from 'send', 'done', 'shell-integration')
Aug 15 19:13:42 iMac systemd[1]: ntfy-sh_notify-send.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Aug 15 19:13:42 iMac systemd[1]: ntfy-sh_notify-send.service: Failed with result 'exit-code'.

Funny it really seems like it got the wrong binaries!

I tried to change back to

/run/current-system/sw/bin/ntfy subscribe topic-bash '/run/current-system/sw/bin/notify-send "$m"'

but then again I get the error:

Aug 14 19:44:16 iMac ntfy-sh_notify-send-start[736]: 2023/08/14 19:44:16 WARN ntfy.sh/topic-bash/tPLIU7TPyIUZ Command failed: exec: "sh": executable file not found in $PATH

Also reboot didn’t help

Is your script still invoking this? That’d be whatever ntfy is in your systemPackages, and not the one in the service definition’s path.

1 Like

hello abathur
no I don’t use it in the script anymore:

systemd.services."ntfy-sh_notify-send" = {
  wantedBy = [ "default.target" ];
  partOf = [ "default.target" ];
  script = ''

#!/run/current-system/sw/bin/bash
${pkgs.ntfy}/bin/ntfy subscribe topic-bash '${pkgs.libnotify}/bin/notify-send "$m"'
path = [pkgs.ntfy-sh pkgs.libnotify];
  '';
};

edit: can you give me a hint on how to use your website :wink:

Per discussion above, it should probably be:

script = ''

#!/run/current-system/sw/bin/bash
-${pkgs.ntfy}/bin/ntfy subscribe topic-bash '${pkgs.libnotify}/bin/notify-send "$m"'
+${pkgs.ntfy-sh}/bin/ntfy subscribe topic-bash '${pkgs.libnotify}/bin/notify-send "$m"'
path = [pkgs.ntfy-sh pkgs.libnotify];
  '';

Also, if you’re specifying the packages as part of the path, you should hopefully just be able to invoke them with a bare ntfy and notify-send (no absolute paths). Said the other way around, using both the path and the interpolation is (likely) an unnecessary duplication of dependencies.

Is something specific tripping you up? The initial prompt should encourage you to run help, which hopefully provides enough suggestions to get you started.

1 Like

thank you abathur

the code looks now like this:

${pkgs.ntfy-sh}/bin/ntfy subscribe topic-bash '${pkgs.libnotify}/bin/notify-send "$m"'
path = [pkgs.ntfy-sh pkgs.libnotify];

and I get the following error:

Aug 16 07:05:31 iMac ntfy-sh_notify-send-start[65052]: 2023/08/16 07:05:31 WARN ntfy.sh/topic-bash/v9nzLaNMBQLy Command failed: exec: "sh": executable file not found in $PATH

So it’s the same error as at the beginning. Can we rule the absolute path vs. pkgs.ntfy syntax out?

1 Like

Try adding pkgs.bash (or any other shell that provides bin/sh) to the path.


Edit:
This was a hunch to clarify that the ntfy package(s?) have an unspecified runtime dependency on sh because I was having trouble hunting it down in the source.

I wouldn’t call it the ~right fix (but it’s an okay workaround on your system).

I do, however, think I’ve found it now: https://github.com/search?q=repo%3Abinwiederhier%2Fntfy%20scriptLauncher&type=code

The package should probably patch the cmd/subscribe_*.go files to use a specific bin/sh from the Nix store at the declaration sites of scriptLauncher in the search above.

They should also probably* be patched in the scriptHeader declarations (which look like they’re used to write shebangs for some kind of runtime codegen) at these sites: https://github.com/search?q=repo%3Abinwiederhier%2Fntfy+scriptHeader+path%3Acmd%2Fsubscribe_*.go&type=code

* I say probably on the latter because I don’t know where it writes these scripts and what their lifetimes are like. If it dumps them in a persistent location (such as ~/) and then doesn’t overwrite existing scripts, the shebangs in the scripts may be able to go stale. (They could then stop working if the shell has been garbage-collected since they were generated…)

1 Like

Abathur, thank you for your magnificent wizardry so far. I will open an issue on github with your post, if this is ok for you?

I added pkgs.bash to the path:

path = [pkgs.bash pkgs.ntfy-sh pkgs.libnotify];

but still the same error when ntfy gets triggered:

● ntfy-sh_notify-send.service
     Loaded: loaded (/etc/systemd/system/ntfy-sh_notify-send.service; enabled; preset: enabled)
     Active: active (running) since Wed 2023-08-16 18:59:50 CEST; 24s ago
   Main PID: 4752 (ntfy-sh_notify-)
         IP: 5.5K in, 1.1K out
         IO: 196.0K read, 0B written
      Tasks: 9 (limit: 38435)
     Memory: 11.3M
        CPU: 47ms
     CGroup: /system.slice/ntfy-sh_notify-send.service
             ├─4752 /nix/store/8fv91097mbh5049i9rglc73dx6kjg3qk-bash-5.2-p15/bin/bash /nix/store/z25mxacndaxagrx061b39sb1q3gm2jlf-unit-script-ntfy-sh_notify-send-start/bin/ntfy-sh_notify-send-start
             └─4753 /nix/store/nvhwk80r7va0504zgwnbbix3giqpj02n-ntfy-sh-2.5.0/bin/ntfy subscribe topic-bash "/nix/store/qxjilpm0jd4ji2p04zym6sl2ldbl5y4k-libnotify-0.8.2/bin/notify-send \"\$m\""

Aug 16 18:59:50 iMac systemd[1]: Started ntfy-sh_notify-send.service.
Aug 16 19:00:09 iMac ntfy-sh_notify-send-start[4753]: 2023/08/16 19:00:09 WARN ntfy.sh/topic-bash/Cdado1Kctp4i Command failed: exec: "sh": executable file not found in $PATH

That’s fine by me. (This also shouldn’t be a terribly complex PR, if you’re interested in trying it.)

Egh. I’m not sure, here.

There are a lot of edge-case possibilities for how the PATH could be getting ~lost or mis-set between the service definition and the run site. I hesitate to speculate much because I’m not sure how the most-obvious cases wouldn’t also be causing trouble outside of the service, and the straightforward fix is still likely patching. (I also see at least one previous Nixpkgs issue with this error message where they did the same.)

Do you know how to use a version of the package overridden with overrideAttrs? If so, you could probably add a postPatch append to the existing postPatch to add a line that does something like below:

(No need to try everything I mentioned before to confirm the change; you can just focus on fixing "sh" in cmd/subscribe_unix.go.)

1 Like