🚀 Alguni Start learning

Unit 8: Your Own Commands

Writing a script, and teaching the machine a new word.

Unit 8 of 8 in Linux and the command line for kids. Its 5 lessons are A File Full of Commands, Making It a Command, Telling It Something, Where Commands Live and A Script Worth Keeping — below is everything each one explains, and a question or two from it to try.

Every terminal session on this page was replayed before it shipped, on a machine whose every message is tested against real bash and coreutils.

This unit opens with a fortnight’s trial of everything — no card needed — or with a family plan, bought in the iPhone app. The first two units of every track are free for ever. Try it in the app.

📜 A File Full of Commands

Type it once, keep it forever

You worked out a clever pipeline. Tomorrow you will have forgotten it.

So put it in a file. A script is nothing more exciting than a list of the commands you would have typed, one per line, saved.

Terminal

kid@alguni:~$ echo "echo counting the files" > count.sh
kid@alguni:~$ echo "ls | wc -l" >> count.sh
kid@alguni:~$ cat count.sh
echo counting the files
ls | wc -l

Running it

bash count.sh hands the file to the shell and says "do all of this".

Each line runs in order, exactly as if you had typed it. Nothing is different — that is the whole idea.

Terminal

kid@alguni:~$ bash count.sh
counting the files
3

Notes to yourself

A line starting with # is a comment. The shell skips it entirely.

Write one at the top of every script saying what it is for. In three weeks you will be very glad you did.

Terminal

kid@alguni:~$ cat both.sh
# say hello
echo hello
# and goodbye
echo goodbye
kid@alguni:~$ bash both.sh
hello
goodbye

Try it yourself

What is a shell script?

  • A file with commands in it, one per line
  • A special kind of program you have to compile
  • A picture of a terminal
  • A folder full of programs

Answer it in the app

⚡ Making It a Command

Back to the x bit

Typing bash count.sh works, but it is not how a real command feels. ls does not need anybody to say bash ls.

Unit 5 already gave you the answer: chmod +x. Add the x and the file becomes a program in its own right.

Terminal

kid@alguni:~$ ./mine.sh
bash: ./mine.sh: Permission denied
kid@alguni:~$ chmod +x mine.sh
kid@alguni:~$ ./mine.sh
I am a real command now

The line at the top

One thing is still missing. When Linux runs the file directly, how does it know the file is *shell* and not Python?

The first line tells it. #!/bin/bash means "run this with the program at /bin/bash". Those two characters are called a shebang, and every script in the world starts with one.

Terminal

kid@alguni:~$ printf "#!/bin/bash\necho hello from a proper script\n" > proper.sh
kid@alguni:~$ cat proper.sh
#!/bin/bash
echo hello from a proper script
kid@alguni:~$ chmod +x proper.sh
kid@alguni:~$ ./proper.sh
hello from a proper script

Why it looks like a comment

It starts with #, so the shell skips it — which is exactly the point. The line is not *for* the shell. It is for Linux, which reads the first two characters of the file before deciding what to do with it.

One line that two different programs read two different ways, and both are happy.

🎯 Telling It Something

Arguments

A script that always does the same thing is not much use. grep would be useless if you could not tell it what to look for.

Whatever you type after the script's name lands in numbered boxes: $1 is the first, $2 the second, and so on.

Terminal

kid@alguni:~$ cat greet.sh
#!/bin/bash
echo "hello, $1"
kid@alguni:~$ ./greet.sh Sam
hello, Sam
kid@alguni:~$ ./greet.sh Ada
hello, Ada

When they forget

What if somebody runs it with nothing after it? $1 is empty and the greeting is half a sentence.

A good script checks. [ -z "$1" ] asks "is this empty?", and exit 1 stops the script there with a verdict of "did not work" — which is exactly the number unit 6 taught you to read.

Terminal

kid@alguni:~$ ./greet.sh
please tell me a name
kid@alguni:~$ echo $?
1
kid@alguni:~$ ./greet.sh Ada
hello, Ada
kid@alguni:~$ echo $?
0

Try it yourself

What does this print?

Terminal

./order.sh apple banana

Answer it in the app

🛤️ Where Commands Live

The list of places to look

Finally, the answer to why it is ./greet.sh and not greet.sh.

When you type a bare name, the shell looks through a list of folders called $PATH — and the folder you are standing in is not on it. which shows you where it found something.

Terminal

kid@alguni:~$ echo $PATH
/usr/local/bin:/usr/bin:/bin
kid@alguni:~$ which ls
/usr/bin/ls
kid@alguni:~$ which grep
/usr/bin/grep

Why yours is not on the list

That is deliberate, and it is a safety rule.

If the current folder were searched first, somebody could leave a file called ls in a shared folder, and the next person who typed ls would run *their* program instead. ./ means "I really do mean this one, right here".

A shorter name for a long command

An alias is a nickname. alias ll="ls -l" and from then on ll means ls -l.

It lasts until you close the terminal. To keep one for ever you put the line in a file called .bashrc in your home folder, which the shell reads every time it starts — and which is hidden, so ls -a is the only way you would ever have found it.

Terminal

kid@alguni:~$ alias ll="ls -l"
kid@alguni:~$ ll
total 4
-rw-r--r-- 1 kid kid 6 Jan  1 09:00 notes.txt
kid@alguni:~$ alias
alias ll='ls -l'

Try it yourself

Why does typing greet.sh not work when ./greet.sh does?

  • The folder you are in is not on $PATH
  • The file is not executable
  • Scripts always need a dot
  • You have to be root

Answer it in the app

🏆 A Script Worth Keeping

Everything, at once

One last job, and it uses the whole track.

You are going to write a backup script: it takes the name of a folder, checks it is really there, makes a copy with -backup on the end, and says how many files it saved.

A file, an x bit, an argument, an if, a cp -r, a pipeline and a variable. Eight units in about six lines.

Where to go now

You can drive a Linux machine. Not a toy one — the commands, the messages, the permissions and the shell are all the real ones.

The next real machine to try them on is a Raspberry Pi, which is a whole Linux computer for the price of a game. Everything in these eight units works on one, exactly as it worked here.

Try it yourself

What is the difference between a shell script and the commands you type?

  • None — a script is those commands, saved in a file
  • Scripts have to be compiled first
  • Scripts use a different language
  • Scripts can only be run by root

Answer it in the app