mw

chmod u+x and ~/bin

Here’s a small recipe for saving scripts.

I often want to save a script and run it by name from a different shell.

I usually start with an empty file.

touch my-script

At this point, I can run the script with sh my-script. But I want the file to be executable, I don’t want to have to execute sh with the file as an argument.

To make it executable I have to give it the executable permission. Since these are personal scripts, I only want to add the permissions to my user. So I chmod with u+x instead of +x. I read this as “user plus executable.”

chmod u+x my-script

Now I can run it with ./my-script.

The system needs to know how to run it, so I’ll give it a shebang (#!). If the file starts with a shebang, the text following the shebang states what program should be used to evaluate the it. If you want /bin/bash to evaluate it, start the script with #!/bin/bash. If you want the script to run as the current environment’s python, you can start the script with #!/usr/bin/env python.

Next, I don’t want to care about the script’s location or relative directories. Plus, I need a place for scripts like this to live. I like ~/bin, but anything works. To make that path available to the current shell, run:

export PATH="$PATH:~/bin"

This adds the ~/bin directory to your PATH. Now when you execute a command, your shell will check in ~/bin/ for an executable with that name. I have this line in my ~/.bashrc (or that shell’s rc file) so it runs for every terminal instance.

Then, once I mv my-script ~/bin/, I can call my-script like I would any other program.

You can combine a few steps with:

echo "echo hi" > ~/bin/my-script
chmod u+x ~/bin/my-script

Side note: this may feel trivial, but there’s a ton of required unix knowledge to understand what’s actually going on. There’s file permissions, $PATH, and lifecycle hooks around a shell. I write posts like this because there shouldn’t be that kind of barrier to entry to getting shit done.