Putting scripts into $PATH
A personal digital multitool
Whenever I find myself doing a task for a third time, it’s probably going to come up again and probably worth writing a script to get it done faster when it does. This is a pretty common habit far from unique, but mine were beginning to get out of hand so I was interested to see Evan Hahn’s post about handling the cutter.
Ditching aliases
Instead of using aliases in bashrc (or in my case usually config.fish) for execution, Evan recommends adding basic scripts to a directory. You can then put that directory in your PATH The $PATH is the list of places where your system looks to find commands it’s being executed. This is different to the common (lowercase) “file path” showing where a file is found. and have the script execute right from your shell, while the directory is version controlled.
The effect is like a personal multitool that’s ready whenever you need it. Maybe obvious in hindsight but quite powerful in practice. Julia Evans also explains how to do this in a very clear way, covering lots of different cases.
I found the idea compelling and started using it straight away.
Doing the thing
I use fish shell (because it just works), so I can use the handy “do what you mean” built-inAlthough Julia Evans warns against this for a couple of reasons, including that it’s hard to undo. to do this:
~> fish_add_path (realpath ./script-path)
The (realpath …) function in the snippet above will be replaced by the full directory path. That will then be added to the PATH.
“Symlinks” is always the answer
One tweak to the setup I use is to have two folders:
/.../scriptsfor the scripts themselves, which is version controlled and- a subdirectory
/.../scripts/script-path, which goes into the PATH.
scripts/
├── myscript.sh
├── .gitignore
└── script-path/
└── myscriptscript-path/ is gitignored and goes on $PATH; the scripts themselves stay under version control in the parent directory.
I can then use git to track the version control in the scripts directory, without needing to have a git history in my PATH (which feels like it could go wrong). So:
/.../scripts ~> mkdir script-path
/.../scripts ~> git init
/.../scripts ~> echo "script-path/" >> .gitignore
All that remains is to add the scripts themselves to the subdirectory. Rather than making copies of the various scripts, symlinks do the job cleanly. This way even when I update the main files, the symlinks still point where I want them to, and the files themselves remain under version control. Add scripts one at a timeThe first time, I did it in bulk. All my existing scripts were named with a .sh extension so in fish: ~> for sh_file in *.sh; set filename_without_extension (string split -r -m1 . $sh_file); ln -s (realpath $sh_file) ./script-path/$filename_without_extension; end with:
ln -s (realpath ./scripts/myscript.sh) ./script-path/myscript
And don’t forget to give all the script files executable permission with chmod +x filename.sh.