zerotoclaude
Module 02/Software Basics/Lesson 06

Running a script from the terminal

Your first real moment of 'I made the computer do a thing on purpose.'

6 min read

Time for the moment that flips a switch in most people's heads: the first time you write a tiny piece of code and run it yourself, and the computer does the thing you told it to do. It's deflatingly simple. It's also one of the most important lessons in this curriculum, because every single thing Claude Code does is, underneath, this.

What "running a script" means

A script is a file containing instructions in some programming language. To run it, you hand the file to a program (called an interpreter) that reads the file and follows the instructions inside, top to bottom.

For Python:

terminal
python hello.py

For Node.js (JavaScript):

terminal
node hello.js

In each case you're saying: "run this interpreter, hand it this file." The interpreter reads, executes, and exits.

The smallest useful script

Let's write a script that does something genuinely handy: renames a folder full of photos so they sort cleanly. We'll do it in Python, because Python is the friendliest reading experience for non-programmers.

Make a folder somewhere — say ~/Projects/rename-demo — and drop a few placeholder image files into it (anything called foo.jpg, bar.jpg, etc. will do). Then in that folder, create a file called rename.py with this content:

python
import os

# The folder we want to rename files in (current folder)
folder = "."

# Get all files in the folder, sorted alphabetically
files = sorted(os.listdir(folder))

# Walk through them, renaming each with a numbered prefix
counter = 1
for filename in files:
    if filename.endswith(".jpg"):
        new_name = f"{counter:03d}-{filename}"
        os.rename(filename, new_name)
        print(f"renamed: {filename} -> {new_name}")
        counter += 1

print("done.")

Read it before you run it. Out loud is fine.

  1. Import the operating system tools.
  2. Set folder to "here."
  3. List all the files, sorted.
  4. For each .jpg file, build a new name like 001-foo.jpg and rename it.
  5. Print what happened.

That's it. You can run it from the terminal in that folder:

terminal
cd ~/Projects/rename-demo
python rename.py

And you'll see something like:

terminal
renamed: bar.jpg -> 001-bar.jpg
renamed: baz.jpg -> 002-baz.jpg
renamed: foo.jpg -> 003-foo.jpg
done.

That is a real, working program. You wrote it. You ran it. It did a thing.

The unlock
Once you've done this once — written a tiny file, run it, watched it work — everything else in software stops feeling like magic. It's all the same trick at different scales.

Arguments: telling the script things at run time

Most useful scripts take input. Maybe you want to tell it whichfolder to rename. You don't have to edit the file every time — you can pass that in on the command line, called a command-line argument.

python
import os
import sys

# sys.argv is a list. The first item is the script name itself.
# The second item is the first real argument the user passed.
folder = sys.argv[1] if len(sys.argv) > 1 else "."

files = sorted(os.listdir(folder))
counter = 1
for filename in files:
    if filename.endswith(".jpg"):
        new_name = f"{counter:03d}-{filename}"
        os.rename(
            os.path.join(folder, filename),
            os.path.join(folder, new_name),
        )
        print(f"renamed: {filename} -> {new_name}")
        counter += 1

print("done.")

Now you can run it on any folder:

terminal
python rename.py ~/Downloads/vacation-photos

And the script renames files in that folder instead of the current one. That tiny change is what makes a script reusable.

Exit codes

When a script finishes, it tells the operating system whether it succeeded or failed via an exit code— a small number. Zero means "success." Anything else means " something went wrong."

You usually don't see exit codes directly, but they matter because other programs check them. When you chain commands together with &&, the second only runs if the first succeeded:

terminal
python rename.py photos/ && echo "all good!"

The echo only fires if python rename.py exits with 0. This is how CI pipelines, deployment scripts, and Claude Code itself decide whether a step worked. Knowing exit codes exist is enough; you don't need to think about them often.

Executable permission and shebangs

On Mac and Linux there's a neater trick: you can make a script directly runnable, without typing python every time. Add this line as the very first line of the file:

python
#!/usr/bin/env python3
import os
...

That funny-looking line is called a shebang. It tells the operating system which interpreter to use. Then mark the file executable:

terminal
chmod +x rename.py
./rename.py photos/

Now ./rename.py works as a command in its own right. On Windows the mechanism is different (file associations) but the same idea: associate the file with an interpreter so you can just run it.

What Claude Code does with scripts

Half of what Claude Code does on your behalf is writing a one-off script, running it, and showing you the output. "Convert these CSV files to JSON." "Find every file in the project that mentions deprecated API X." "Generate placeholder images for the design."

Each of those is a script Claude writes and runs, then deletes (or keeps, if you want to reuse it). You now understand exactly what is happening under the hood when you watch that scroll past.

What to take with you
  • A script is a file with instructions. You run it by handing it to an interpreter (python file.py, node file.js).
  • Command-line arguments let you reuse a script with different inputs without editing the file.
  • Exit code 0 = success, anything else = failure. Other programs (and Claude Code) use this to decide what to do next.
  • A shebang line + executable permission lets you run a script like its own command.
  • Almost everything Claude Code does on your data is, underneath, a script. You now know how that machinery works.