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