Getting ENV vars inside of writeShellApplication

I found a workaround, but is this the right approach for getting env vars inside of writeShellApplication?

I’ve been migrating some of my scripts over to my NixOS config and I had some trouble getting a tmux sessioniser script to work for me. The general idea is to open an fzf window with a list of directories and start a session, or attach to the existing session for that dir.

I got the script from here but had to add the final check at the end or it just fails if you’re not in a tmux session.

My script passed shellcheck and I was about to build it, but when I ran it would crash with complaints about an unbound variable for $TMUX. writeShellApplication sets nounset so that explains why I get an error, but I want to get that var from env vars, and if it doesn’t exist, that’s fine because I am checking for it with -z.

Technically correct is the best kind of correct, after all, and $TMUX is not defined in my script so it makes sense to throw here. I was trying to find a good way to get an env var if it exists, and I guess default to nothing if not.

I tried a few options and I have something that works now, but I was curious if there’s a smarter way to do this.

My workaround was this line: TMUX=$(printenv TMUX || echo "")

Here’s the snippet in question.

# I set selected and selected name above

# checks for the process
tmux_running=$(pgrep tmux)

# tmux sets the $TMUX env var when you're in tmux
TMUX=$(printenv TMUX || echo "") # had to do this for nix

# if tmux isn't running at all, create new session
if [[ -z "$TMUX" ]] && [[ -z "$tmux_running" ]]; then
    tmux new-session -s "$selected_name" -c "$selected"
    exit 0
fi

# tmux is running, check if session exists first and create if not
if ! tmux has-session -t="$selected_name" 2> /dev/null; then
    tmux new-session -ds "$selected_name" -c "$selected"
fi

# session exists, switch or attach
if [ "$TMUX" ]; then
  tmux switch-client -t "$selected_name"
else
  tmux a -t "$selected_name"
fi

I don’t think printenv is necessary here. https://mywiki.wooledge.org/BashFAQ/112 provides some context on nounset, including how to work around the error.

writeShellApplication is opinionated, but nothing about Nix or nixpkgs compel us to use it over a less-opinionated approach as needed.

${TMUX-}

See the Bash manual.

${foo:-val} $foo, or val if unset (or null)

error: undefined variable 'TMUX-'
       at /nix/store/67dswch85d4fzfajbmk1p5lammkqlbyf-source/homeManagerModules/tmux/scripts.nix:32:20:
           31|         # if tmux isn't running at all, create new session
           32|         if [[ -z ${TMUX-} ]] && [[ -z "$tmux_running" ]]; then

It seems like writeShellApplication is very opinionated .

I tried parameter expansion before resorting to printenv. I just double checked again though in case I was doing something dumb.

${TMUX:-} doesn’t work and neither does ${TMUX-default}

I guess printenv works fine in this case, because I liked having pkgs specified as runtimeInputs, and shellcheck running.

We baited you, unfortunately. It wasn’t clear here that your script is actually inlined in a .nix file.

You’ll need to escape it. Assuming this is in a double-quoted '' multiline string, that should look like: ''${TMUX-}

1 Like

Escaping it did the trick. I probably should have just posted the whole file with writeShellApplication in there to make it more clear. Thanks for the help!

1 Like