writeShellApplication not running bash script as you would expect

I’m trying to include all/most of my scripts(bash, python) in my nix config. During the conversion of the second script I’m running into a weird situation.
The script runs fine using ./genpasswd.sh


It doesn’t give the output I expect when running through nix using genpasswd


I have no idea why this happens. It passes shellcheck, and it builds through nix

bash script genpasswd.sh :

#!/usr/bin/env bash


genpasswd() {
  local l=${1:-$DEFAULT_LENGTH}
  echo 11
  pass="$(tr -dc "$characters" < /dev/urandom | head -c "$l" | xargs)"
  echo 22
  echo "$pass"  # print
  echo "$pass" | wl-copy --paste-once --trim-newline  # clipboard
  return 0

_main() {
  genpasswd "${@}"

_main "${@}"
environment.systemPackages = with pkgs; [
    (pkgs.writeShellApplication { 
      name = "genpasswd";
      runtimeInputs = with pkgs; [ coreutils wl-clipboard findutils ];
      text = builtins.readFile ../../scripts/genpasswd.sh;

So if you take a look at the script created by writeShellApplication, it uses:

set -o errexit
set -o nounset
set -o pipefail

So the script will exit if any pipe fails. Since head closes the pipe before tr could read everything from /dev/urandom, tr will return exit status 141 and the script exits.

You can either disable pipefail for that line (set +o pipefail) or add a || true.
I’d probably write it like this:

pass="$(tr -dc "$characters" < /dev/urandom | head -c "$l" || true; echo)"