Sign in
← Terminal: bash scripts
3 min · easy · Lesson 1 of 5

Your first bash script

Create an executable script that prints hi.

Why

A deploy script, a backup script, a log-rotation script: they're all built the same way. It's a text file with commands you'd otherwise have to type by hand. For the system to run such a file as a program, it needs two things. The first line says which interpreter reads it. And the file needs the execute bit set.

If either is missing, the script won't start. The errors are short and confusing: Permission denied, command not found, cannot execute: required file not found. This lesson covers where each one comes from.

Concepts

A script is a plain text file with shell commands, one per line. The shell runs them top to bottom, as if you typed them in one after another.

A shebang is the first line of a script, starting with #!. After #! comes the full path to the interpreter: #!/bin/sh or #!/bin/bash. When you run the script as a program, the kernel reads this line and hands the file to that interpreter.

The execute bit (x in the permissions) lets you run a file as a program. A new file doesn't get it: with the usual 022 mask it's created with rw-r--r-- permissions. chmod +x sets the bit.

PATH is a variable holding a list of folders where the shell looks for a command whose name has no / in it. The current folder isn't on that list.

How it works

Writing the file

There's no text editor in the lab, so it's easiest to create the file from the command line. The construct cat > file <<'EOF' writes everything you type, up to the line EOF, into the file:

cat > /root/greet.sh <<'EOF'
#!/bin/sh
echo hello
EOF

The quotes around 'EOF' stop the shell from expanding variables inside the text: exactly what you typed lands in the file. A short script can also go in one command, where \n means a line break:

printf '#!/bin/sh\necho hello\n' > /root/greet.sh

Check what you got:

cat /root/greet.sh
#!/bin/sh
echo hello

#!/bin/sh or #!/bin/bash

/bin/sh is the POSIX shell. On Ubuntu and Debian it's a link to dash, a small, fast shell. On Alpine it's busybox sh. For simple scripts with echo, variables, if, and loops, it's enough.

#!/bin/bash is for when you need bash-specific features: arrays, [[ ... ]], $'...'. Minimal images like Alpine don't have bash by default, and such a script won't run there.

ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Mar 31  2024 /bin/sh -> dash

On another system the link may point somewhere else.

The execute bit

A file you just created can't be run as a program yet:

ls -l /root/greet.sh
-rw-r--r-- 1 root root 21 Oct 10 10:00 /root/greet.sh
/root/greet.sh
bash: /root/greet.sh: Permission denied

chmod +x adds x for the owner, the group, and everyone else (subject to umask); chmod u+x adds it only for the owner:

chmod +x /root/greet.sh
ls -l /root/greet.sh
-rwxr-xr-x 1 root root 21 Oct 10 10:00 /root/greet.sh

Permissions and the numeric notation are covered in the "Permissions" lesson.

Three ways to run it

Just greet.sh without a path won't work, even if you're in the same folder:

greet.sh
bash: greet.sh: command not found

The shell only looks for a command without / in the folders listed in PATH, and the current folder isn't one of them. To run a script by name, put it in one of those folders, for example /usr/local/bin.

What the shebang does

If you run the file as a program (./greet.sh), the kernel looks at the first two bytes. It sees #!, takes the path from the first line, and runs /bin/sh /root/greet.sh. So the path has to be exact: a typo like #!/bin/shh means the kernel can't find the interpreter.

bash: ./greet.sh: cannot execute: required file not found

That's what bash prints. Run it from sh (dash) and the text differs: ./greet.sh: not found. The meaning is the same either way: the script file exists, but there's no interpreter at the path from the shebang.

Without a shebang, the behavior depends on who runs it. Bash and dash will run such a file as a script on their own, but a program that calls it directly (for example, docker exec or systemd) gets an exec format error. That's why you always write a shebang.

Common mistakes

What you'll need for the tasks

Practice in your browser

Linux runs right here. Solve the task and we'll save your progress automatically.

01

Script /root/hello.sh

Create the file /root/hello.sh so that running it prints the line hi. Make the file executable (chmod +x) so you can run ./hello.sh.

{ i }

Go through it with an AI agent

The agent explains anything unclear in plain words, gives you 2 labs for this lesson and drills you on interview questions. $49 one-time, lifetime access.

Get access for $49

Tell the agent: use MCP izi, give me lesson terminal-scripts-01-hello-script