Executing bash by a nix program

Hi !
I would like to configure my Tinc VPN on a computer. And when it starts, tinc have to run Bash commands (just a ip set and ip route)

I have this configuration :

  environment.etc = {
      "tinc/vpnforky/tinc-up".source = pkgs.writeScript "tinc-up-vpnforky" ''
          #!/bin/sh
          ip link set $INTERFACE up
          ip addr add 10.0.0.100/32 dev $INTERFACE
          ip route add 10.0.0.0/24 dev $INTERFACE
      '';
      "tinc/vpnforky/tinc-down".source = pkgs.writeScript "tinc-down-vpnforky" ''
          #!/bin/sh
          ip addr del 10.0.0.100/32 dev $INTERFACE
          ip route del 10.0.0.0/24 dev $INTERFACE
          ip link set $INTERFACE down
      '';
  };

But I always have “ip command not found” as output. (I translated the error in english)

sept. 25 09:02:16 nixos tincd[6377]: /etc/tinc/vpnforky/tinc-up: ligne 2: ip : command not found
sept. 25 09:02:16 nixos tincd[6379]: /etc/tinc/vpnforky/tinc-up: ligne 3: ip : command not found
sept. 25 09:02:16 nixos tincd[6380]: /etc/tinc/vpnforky/tinc-up: ligne 4: ip : command not found 

I tried to use ${pkgs.stdenv.shell} or “sudo” but nothing changed :frowning: Do you have a solution ?

Command-not-found errors mean that a PATH lookup for the command has failed (it isn’t in any of the directories listed in the PATH environment variable). You’ll either need to add it to the PATH or invoke ip by absolute path.

Since you’re already inlining the scripts, the easiest approach is to just inline the absolute paths as well. I think it’s in the iproute2 package, so that would look something like:

${pkgs.iproute2}/bin/ip link set $INTERFACE up

I wrote about different ways you can use Nix to provide dependencies for shell scripts this summer: no-look, no-leap Shell script dependencies

2 Likes

You should probably set the hashbang to a nix store path as well, just to keep the dependency fully resolved. (/bin/sh will change with updates, a nix store path won’t, not that it normally matters much for something like sh)

So: #! {pkgs.bash}/bin/bash (unless you really want it to be sh for some reason).

1 Like

Thanks for the advice :slight_smile: I’m used to setting the hashbang like this : " ${pkgs.stdenv.shell}" but you’re right : I should use Bash instead of shell