Rake Routes

by Stephen Ball

What’s a $PATH anyway?

You’ve probably seen $PATH or just PATH before as the place you need to add new commands for your prompt. What is that? Where is it? How does it work?

High Level: What’s the $PATH?

$PATH is a shell variable that holds an ordered list of all the directories that your shell will search within when you tell it to run a command.

Commands, how do they work?

When you run a command like date in your prompt your shell first looks to see if that command matches any built-in” commands. If so it will run that built-in command that’s actually part of the shell itself.

If the command doesn’t match a built-in then your shell examines the $PATH variable to see all the directories that it’s allowed to search in to find a command to run. Starting with the first it checks each directory and when it finds an executable file with a filename matching your command then it will execute it with any arguments you’ve given.

$PATH in action

First open up your prompt.


Great! Now let’s examine what the shell would run for various commands. We can do that with a command called which. Given a command, which tells you what the shell would run.

$ which date

There we see that if we were to run the date command, the shell would find and execute /bin/date.

Let’s get meta on it.

# In zsh which is a built-in
$ which which

# In bash which is an actual command
$ which which

Let’s try something that might give you some more interesting results.

$ which ruby

On the machine I’m writing this post on I use the excellent asdf to manage my Ruby installation. When I ask my shell what it would run for ruby I find that it wouldn’t actually call a specific Ruby version, but this asdf shim. In that way asdf can control which Ruby version it uses depending on the current shell or project settings.

Ok, but what does it do?

You can add your own directories to the $PATH so you can easily add new executable commands to your command line environment! Woo!

The syntax is weird, but the gist is that you want to add your new directories to the PATH variable without interfering with what’s already there. You do that be declaring the new PATH variable to be the original PATH variable plus your own stuff. The directories are each separated with a: character.

What’s on $PATH already?

If you want to see what your PATH variable already has you can use the echo command. The echo command prints all of its arguments to STDOUT.

$ echo $PATH

If you want some nicer formatting let’s translate those : characters into newlines with the tr command.

$ echo $PATH | tr : "\n"


Your own bin directory

In your .bashrc or .zshrc or similar shell startup file you can add a line like this:

export PATH="$HOME/bin:$PATH"

That says to make $HOME/bin the first place the shell checks for any command before going on to check whatever was already configured.

I highly recommend having a bin directory in your home directory in your PATH variable. That gives you an easy place to place new shell scripts or your own custom commands.

If you’d like to see what I keep in bin feel free to look! My bin directory is a public part of my dotfiles repo.

Up next Let’s Use Hwacha to Scan URLs I’ve written a gem, Hwacha, as a wrapper around Typhoeus to allow for quick and easy response checking for multiple URLs. Let’s go through some Let’s write a shell script Now that you have a $PATH let’s start using it! Today we’ll write a simple shell script in your personal bin directory. Let’s start by picking the
Latest posts Where did the recent Elixir posts go? A subtle Go bug that types cannot help with swapcase with the tr command nice go test output See where vim settings came from Containers in the real world and backpressure in distributed systems Elixir Phoenix and “role postgres does not exist” From awk to a Dockerized Ruby Script Finding leap years with the cal command The Problem of State Clojure Functions in Four Ways See Some Clojure A simple language spec isn’t a feature when you’re building applications The Fastest Possible Tests Shrink your data into bitfields (and out again) Every “if” statement is an object waiting to be extracted Choose Generic Tools Hyperlinks you might find interesting — #4 Running bundle install on rails master Use tldr for command line examples Friday Lunch Links — #3 Friday Lunch Links — #2 Logical Solver: Turn facts into conclusions Programming with jq Command line tools - jq Friday Lunch Links — #1 Why diversity matters Music for coding - October 2019 Code puzzles are a poor way to gauge technical candidates Add vim to a pipeline with vipe Connecting Objects with Observable