Should a package using grep, sed, awk, coreutils, etc, list them as buildInputs and wrap them all?

I have been using quilt to manage patches, and its derivation lists these as buildInputs:

buildInputs = [ makeWrapper perl bash diffutils patch findutils diffstat ];

And its main script its wrapped to find those inputs:

postInstall = ''
  wrapProgram $out/bin/quilt --prefix PATH : \

But I’ve also found that its scripts also use grep, sed, awk, stat, cp, mv, rm, cat, getopt, column, etc.

Should then gnugrep, gnused, gawk, coreutils and unixtools.getopt added to buildInputs
and also to wrapProgram? Or they are so common that they are expected to be present in the system?

makeWrapper should be in nativeBuildInputs.

If the build process doesn’t pick these up and adds their full paths to the final binary (or script), then they should be wrapped too. These programs may be in a typical PATH, but it is still an impurity – the program relies on a certain external state to be present. This may not always be the case, e.g. when a program is run in a sandbox or packaged in a Docker container.

Another comment (without looking at the derivation or knowing quilt), but if perl, bash, diffutils, etc. are only used in the wrapper, they do not have to be in buildInputs.

1 Like

IDK I’d there is a policy but I prefer to pin all runtime dependencies. Especially because commands can be run from inside wrapped commands with a very spartan path.

I’ve found another case. fzf installs shell scripts that should be sourced by the shell. These scripts use perl, find, grep, sed, awk, cut, rm and ps, but only perl is patched:

substituteInPlace shell/key-bindings.bash \
  --replace " perl -n " " ${perl}/bin/perl -n "

Since these are scripts that are sourced by the shell, there is not executable to wrap with the proper paths, so that’s why it is patched directly in the file.

I would think that find, grep, sed, etc should also be patched with the proper store locations. Is it an oversight or the logic is that these are too common and more likely to be present in the system, so there is no need to pin them, they will be in the path.


anything in coreutils is usually present in all contexts, so they don’t usually need to be patched:

$ ls /nix/store/w9wc0d31p4z93cbgxijws03j5s2c4gyf-coreutils-8.31/bin/
[         chmod      date       expand  id       mkdir   numfmt    pwd        sha256sum  stdbuf   touch     unlink
b2sum     chown      dd         expr    install  mkfifo  od        readlink   sha384sum  stty     tr        uptime
base32    chroot     df         factor  join     mknod   paste     realpath   sha512sum  sum      true      users
base64    cksum      dir        false   kill     mktemp  pathchk   rm         shred      sync     truncate  vdir
basename  comm       dircolors  fmt     link     mv      pinky     rmdir      shuf       tac      tsort     wc
basenc    coreutils  dirname    fold    ln       nice    pr        runcon     sleep      tail     tty       who
cat       cp         du         groups  logname  nl      printenv  seq        sort       tee      uname     whoami
chcon     csplit     echo       head    ls       nohup   printf    sha1sum    split      test     unexpand  yes
chgrp     cut        env        hostid  md5sum   nproc   ptx       sha224sum  stat       timeout  uniq

most likely