Your First Script

A script is a file of commands that starts with the shebang line #!/usr/bin/env bash and explains itself in comments; chmod +x lets it run, and ./ and its name runs it from the folder it's in.

Apprentice · Unix · Linux · Updated

After this lesson you can

  • Write a script file that starts with a shebang line naming bash, and explains itself in comments
  • Make a script runnable with chmod +x and run it with ./ from its folder, or with bash and its name

Key takeaways

  • A script is a text file of commands, run top to bottom. The name ending .sh tells people and editors it's a shell script.
  • The first line, #!/usr/bin/env bash, read "shebang", says which program runs the file. It must be the very first line.
  • A line starting with # is a comment, a note for people that bash skips.
  • A new file may not run. chmod +x morning.sh lets it run, and ./morning.sh runs it from the folder it's in.
  • bash morning.sh runs a script without the x permission, which is handy for a quick try.

Every morning this week you've opened a terminal and typed the same commands: a greeting to yourself, date, cat on your to-do list, and df -h to check the disk isn't filling up. Four commands is a small thing, but it's every single day, and on the busy mornings you skip the disk check and forget it for a month. Put the commands in a file, and one word does them all, in order, every time. That file is your first script, and it's how every automation people get paid for starts.

Make a practice folder with a to-do list in it. These lines are safe to run again:

mkdir -p ~/terminal-practice/morning && cd ~/terminal-practice/morning
printf 'pay the phone bill\nfinish the history essay\nbuy coffee beans\n' > todo.txt

A file of commands

Open a new file in nano (Editing in the Terminal: nano) with nano morning.sh, and type these lines:

#!/usr/bin/env bash
# morning.sh: my start-of-the-day check.
# Greets me, then shows the date, my to-do list and the free disk space.

echo "Good morning, $USER!"
date '+Today is %A, %B %d.'

echo
echo "To do:"
cat todo.txt

echo
echo "Free disk space:"
df -h ~

Save with Ctrl+O and Enter, and quit with Ctrl+X. Every line below the first three is a command you could type at the prompt. $USER is the environment variable that holds your user name (Environment Variables: export and env). date with a + and a pattern prints the date your way: %A is the day's name, %B the month's and %d the day's number. echo on its own prints an empty line, to space the output out.

A script runs its lines from top to bottom, the way a cook follows a recipe. The name ending .sh is a habit, not a rule: it tells people and editors that this is a shell script.

The first line: #!/usr/bin/env bash

The first line tells the computer which program should run the file. It starts with #!, read "hash bang" and usually shortened to shebang. After it comes the program: /usr/bin/env bash means "find bash in the folders on my PATH, and run this file with it".

Why not write #!/bin/bash? On Linux it would work. But a Mac's /bin/bash is version 3.2, from 2006, and the bash 5 you installed with Homebrew lives in a different folder. env finds whichever bash comes first on your PATH, so the same script runs on both. The shebang must be the very first line, with nothing before it, not even a blank line.

Comments: notes for people

Lines two and three start with # (read "hash"). That makes them comments: notes for people, which bash skips. The shebang looks like a comment too, and for bash it is one; only the computer, when it starts the file, reads it.

Write at least one comment at the top of every script: what it does, and anything future you would want to know. In three months, # Greets me, then shows the date, my to-do list and the free disk space. saves you reading every line. A comment can also go at the end of a command, after a space: df -h ~ # the drive my home folder is on.

chmod +x, then ./ and its name

Run it the way you ran the kettle-bot in Permissions: Read, Write and Run: ./ (read "dot slash": this folder, this file) and its name.

./morning.sh
ls -l morning.sh
bash: ./morning.sh: Permission denied
-rw-r--r-- 1 sam sam 262 Nov  9 06:08 morning.sh

A new file can be read and changed, but there's no x in its permissions, so it may not run. chmod +x adds it, once:

chmod +x morning.sh
./morning.sh
Good morning, sam!
Today is Monday, November 09.

To do:
pay the phone bill
finish the history essay
buy coffee beans

Free disk space:
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdd       1007G   30G  926G   4% /

That's your first application, running. Yours shows your name, today's date and your own disk. On a Mac, the disk line names a different drive.

There's a second way to run a script: hand it to bash yourself, with bash morning.sh. Bash reads the file, so it needs only read permission, not x. It's handy for a quick try, but a script you'll keep should get chmod +x and its shebang, so it runs like any other program.

Try it in the terminal

Terminal Quest: Mission Control, goal 1: played right on the lesson page.

Launch day at Mission Control, and the flight director wants scripts, not clicks. Read her briefing: it lists the jobs your scripts will do, and how to write the first one.

Check yourself

2 questions to try on the lesson page.

So what

A shebang, a comment, a few commands and chmod +x: that's a whole application. Every script you write from now on, however big, starts exactly like this one.

Key terms

Cheat sheets

Related