2

I have the following definition:

 hello123 = (pkgs.writeScriptBin "finderapp" '' #!${pkgs.stdenv.shell} # Call hello with a traditional greeting ls ${pkgs.ffmpeg-full}/bin/ffmpeg ffmpeg --help echo hello '' ); 

And the service:

 systemd.services = { abcxyz = { enable = true; description = "abcxyz"; serviceConfig = { WorkingDirectory = "%h/temp/"; Type = "simple"; ExecStart = "${hello123}/bin/finderapp"; Restart = "always"; RestartSec = 60; }; wantedBy = [ "default.target" ]; }; }; 

However, this seems to fail being able to execute ffmpeg:

Jul 10 19:47:54 XenonKiloCranberry systemd[1]: Started abcxyz. Jul 10 19:47:54 XenonKiloCranberry finderapp[10042]: /nix/store/9yx9s5yjc6ywafadplblzdfaxqimz95w-ffmpeg-full-4.2.3/bin/ffmpeg Jul 10 19:47:54 XenonKiloCranberry finderapp[10042]: /nix/store/bxfwljbpvl21wsba00z5dm9dmshsk3bx-finderapp/bin/finderapp: line 5: ffmpeg: command not found Jul 10 19:47:54 XenonKiloCranberry finderapp[10042]: hello 

Why is this failing? I assume it's correctly getting ffmpeg as a runtime dependency (verified with nix-store -q --references ...) as stated in another question here: https://stackoverflow.com/a/68330101/1663462


If I add a echo $PATH to the script, it outputs the following:

Jul 10 19:53:44 XenonKiloCranberry finderapp[12011]: /nix/store/x0jla3hpxrwz76hy9yckg1iyc9hns81k-coreutils-8.31/bin:/nix/store/97vambzyvpvrd9wgrrw7i7svi0s8vny5-findutils-4.7.0/bin:/nix/store/srmjkp5pq8c055j0lak2hn0ls0fis8yl-gnugrep-3.4/bin:/nix/store/p34p7ysy84579lndk7rbrz6zsfr03y71-gnused-4.8/bin:/nix/store/vfzp1mavwiz5w3v10hs69962k0gwl26c-systemd-243.7/bin:/nix/store/x0jla3hpxrwz76hy9yckg1iyc9hns81k-coreutils-8.31/sbin:/nix/store/97vambzyvpvrd9wgrrw7i7svi0s8vny5-findutils-4.7.0/sbin:/nix/store/srmjkp5pq8c055j0lak2hn0ls0fis8yl-gnugrep-3.4/sbin:/nix/store/p34p7ysy84579lndk7rbrz6zsfr03y71-gnused-4.8/sbin:/nix/store/vfzp1mavwiz5w3v10hs69962k0gwl26c-systemd-243.7/sbin 

Or these paths basically:

/nix/store/x0jla3hpxrwz76hy9yckg1iyc9hns81k-coreutils-8.31/bin /nix/store/97vambzyvpvrd9wgrrw7i7svi0s8vny5-findutils-4.7.0/bin /nix/store/srmjkp5pq8c055j0lak2hn0ls0fis8yl-gnugrep-3.4/bin /nix/store/p34p7ysy84579lndk7rbrz6zsfr03y71-gnused-4.8/bin /nix/store/vfzp1mavwiz5w3v10hs69962k0gwl26c-systemd-243.7/bin /nix/store/x0jla3hpxrwz76hy9yckg1iyc9hns81k-coreutils-8.31/sbin /nix/store/97vambzyvpvrd9wgrrw7i7svi0s8vny5-findutils-4.7.0/sbin /nix/store/srmjkp5pq8c055j0lak2hn0ls0fis8yl-gnugrep-3.4/sbin /nix/store/p34p7ysy84579lndk7rbrz6zsfr03y71-gnused-4.8/sbin /nix/store/vfzp1mavwiz5w3v10hs69962k0gwl26c-systemd-243.7/sbin 

Which shows that ffmpeg is not in there.

4
  • Call ${pkgs.ffmpeg-full}/bin/ffmpeg --help. Best practice is not to rely on PATH lookups unnecessarily. Commented Jul 10, 2021 at 19:06
  • (Same reasoning behind nix best practices using rpath when dynamically linking instead of trying to build a LD_LIBRARY_PATH to dependencies) Commented Jul 10, 2021 at 19:07
  • Is there an alternative to that? The question is a simplified example. Right now I have a built app that relies on ffmpeg being accessible in the PATH. Commented Jul 10, 2021 at 19:09
  • 2
    The usual approach is for the derivation for that app to itself include a wrapper that puts ffmpeg in its PATH before starting the real/underlying executable. Commented Jul 10, 2021 at 19:33

2 Answers 2

5

I don't think this is the most elegant solution as the dependencies have to be known in the service definition instead of the package/derivation, but it's a solution none the less.

We can add additional paths with path = [ pkgs.ffmpeg-full ];:

abcxyz = { enable = true; description = "abcxyz"; path = [ pkgs.ffmpeg-full ]; serviceConfig = { WorkingDirectory = "%h/temp/"; Type = "simple"; ExecStart = "${hello123}/bin/finderapp"; Restart = "always"; RestartSec = 60; }; wantedBy = [ "default.target" ]; }; 
Sign up to request clarification or add additional context in comments.

Comments

4

In addition to the previous answers

  • not using PATH
  • adding to PATH via systemd config

you can add it to the PATH inside the wrapper script, making the script more self-sufficient and making the extended PATH available to subprocesses, if ffmpeg or any other command needs it (probably not in this case).

The ls command has no effect on subsequent commands, like it shouldn't.

What you want is to add it to PATH:

 hello123 = (pkgs.writeScriptBin "finderapp" '' #!${pkgs.stdenv.shell} # Call hello with a traditional greeting PATH="${pkgs.ffmpeg-full}/bin${PATH:+:${PATH}}" ffmpeg --help echo hello '' ); 

The part ${PATH:+:${PATH}} takes care of the : and pre-existing PATH, if there is one. The simplistic :${PATH} could effectively add . to PATH when it was empty, although that would be rare.

2 Comments

Although this is a solution, it seems like a workaround. Is there maybe a reason why this does not work in a systemd unit context? As like mentioned the expected dependency is listed when doing nix-store -q --references...?
These things (bash, Nix, PATH) work as intended. By what mechanism did you expect your finderapp script to find ffmpeg without setting PATH?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.