Executable & symlink behave differently

Problem as encountered

I use z as an intregral part of my workflow, specifically z.lua, in general, an alternative cd with long history and expressive matching & ranking with ‘frecency’. Installed from nixpkgs.

My tools are not behaving, this will be a learning experience.

Normal usage (z.lua symlinked as z):

$ z -l | wc -l
-bash: /nix/store/03j6z2lbbqv85ajrd1ckbcbns378z6p9-lua-5.2.4/bin/lua: No such file or directory

z fails.

$ z.lua -l | wc -l

z.lua succeeds.

They point to the same executable. z is a symlink in the z-lua package to the z.lua executable.

~$ realpath `which z z.lua`

Invoked as z.lua it can read & print history, and echo usage, but cannot do it’s primary function of changing directory, to a hinted location.


I think I have a few conclusions.

  1. I need to fix the dependency specification for this package (aforementioned learning)
  2. I’m curious why invocation as z.lua fails to trigger an error, but it seems neigh certain this is a quirk of lua, not nix.

This post may just be a log of my learnings & thinking aloud.

Debugging note:
  • Bash has not cached path, this fails in new shells too, hash -l z z.lua returns nothing.


I do have 5 distinct version of lua-5.2.4 installed, with differing binaries, shared library file, and pkgconfigs — though pkgconfig differences are only due to differing paths, and the included header files are identical.

Arrived at with lots of fun of chained fd, xargs, md5sum, sort, awk (attempted), & ulitmately pyp / pypyp.

In your shell is z the alias created by --init or is it the backwards compatibility symlink?

$ type z
z is /nix/store/q1w4xgww2hw5f15cwxsr506z2n2yp5as-z-lua-1.8.16/bin/z
$ eval "$(z.lua --init bash)"
$ type z
z is aliased to `_zlua'

Only the function _zlua is capable of changing the shell’s working directory.

1 Like

Good answer, thank you. In my shell, both are defined, so z as alias takes priority.

I snapshot $(z.lua --init bash) to a file, which appears to be my problem. I think I did this to reduce shell startup time—looks like 15ms to 3ms, under no load, but things add up. My old alias was calling the old version. Don’t understand why, but invoking them, z and z.lua directly, still reports lua version error.

It looks like I can’t use bkt --modtime <file> -- z --init bash to cache the value until z is updated, modification times are not valid in the nix store.

I can’t quite think through all of what’s happening here.

I think I should make a flake that depends on z-lua, to do the caching I want (or upstream it) and bump the version manually (or do some version following / pass-through?). It’s too frustrating to juggle these pieces, remember them on upgrades.

Relevant pieces

component path contribution / role
fs /nix/store/{…} flakes & profiles
fs home .nix-profile current profile
tmux env (g) tmux show-env -g carrying PROMPT_COMMAND to new shells
z --init bash > z-init.snapshot.bash cache/snapshot of init, 15ms->3ms, unloaded system
in .bashrc . [snapshot] load snapshot