Programming with AI
ENRU
F

The terminal — the necessary minimum

twenty commands that are enough

What it is

As much terminal as you need to run your own programs, read logs and understand what an AI is proposing. The examples are Linux and macOS; on Windows the same things are available through PowerShell or WSL.

Where am I and what's here

pwd                 # which folder am I in
ls                  # what's here
ls -la              # everything, hidden files included, with sizes and dates
cd project          # go into a folder
cd ..               # up one level
cd                  # home

Hidden files are the ones starting with a dot: .env, .gitignore. Without -la you can't see them, and that is exactly why they get forgotten.

Look at a file

cat app.py          # the whole thing
head -20 app.py     # the first 20 lines
tail -20 app.py     # the last 20
tail -f logs/app.log  # the last ones, then live as they arrive
wc -l app.py        # how many lines

tail -f is the key command when debugging a running program: leave it in a separate window and watch what gets written while you press buttons.

Find

$ grep -rn "error" logs/
logs/app.log:1:error
logs/app.log:3:error again

$ find . -name "*.py"
./app.py

$ grep -c "error" logs/app.log
2

grep -rn is recursive, with line numbers. It is the command you use to find where a function is used in the project, where a setting is read from, and whether a key got into the code:

grep -rn "sk-\|password\|api_key" .

Files

cp file copy            # copy
cp -r folder copy       # copy a folder
mv old new              # move or rename
rm file                 # delete, with no recycle bin
mkdir -p a/b/c          # create folders, intermediate ones included
du -sh .                # how big a folder is

Running and stopping

python3 app.py          # run it
Ctrl+C                  # stop a running program
Ctrl+D                  # end input (leave python, leave ssh)
./script.sh             # run a script
chmod +x script.sh      # allow it to be run

If ./script.sh answers Permission denied, the chmod +x is missing.

Chaining commands

command1 && command2    # the second only if the first succeeded
command1 | command2     # the first's output into the second's input
command > file          # output into a file (overwrite)
command >> file         # append to the end
command 2>&1            # errors to the same place as normal output

&& is what every build command is made of: tsc -b && vite build means "check the types, and only build if that worked" (article 12.1).

The exit code

$ python3 -c "import sys; sys.exit(3)"
$ echo $?
3

$? is how the last command ended. Zero means "successfully", anything else doesn't. Both && and the checks in a build run on this: a program can print "done" and still return an error.

Environment variables

PORT=8080 python3 app.py     # set for this run only
export API_KEY=abc           # set for the whole terminal session
echo $API_KEY                # look at it
env | grep API               # list the matching ones

A variable set with export lives until the window is closed and doesn't land in any file — which is what makes it good for keys (article 13.4).

What else comes in handy

history | grep docker    # what did I type about docker
Ctrl+R                   # search the command history
curl -s -o /dev/null -w "%{http_code}\n" localhost:8000/   # the response code
df -h                    # how much disk space there is
ps aux | grep python     # which processes are running
kill <number>            # stop a process

The curl command from that list is worth memorizing: it answers "is my server alive at all?" without a browser and without guessing (article 14.3).