Skip to content
Laviyx Learn

Try

Linux and Bash course menu

Bash Scripting Tutorial: Write Your First Shell Script

Write and run your first Bash script: the shebang line, chmod +x, comments, echo and read, here documents, and when to use a script instead of Python.

Intermediate6 min readUpdated
On this page

A script is a text file of commands. Anything you repeat, you can put in a script, and then run it with one word.

Write a script#

Create a file called hello.sh. You can use nano hello.sh. In this course, we use cat with a "here document", which writes the lines up to EOF into a file, so that every example can be copied in one go:

Terminal
cat > hello.sh <<'EOF'
#!/bin/bash
# Greets the user and shows the time.
echo "Hello, $USER"
echo "Today is $(date +%A)"
EOF
  • #!/bin/bash is the shebang. It says which program should run the file, and it must be the first line.
  • Lines starting with # are comments.
  • Everything else is what you would type in the terminal.

Run it#

Make it executable, then run it with ./:

Terminal
chmod +x hello.sh
./hello.sh | sed 's/Today is .*/Today is .../'
Output
Hello, asha
Today is ...

The ./ means "in this folder". The current folder is not in PATH, so plain hello.sh gives "command not found".

You can also run it with bash hello.sh, which needs no execute permission.

Input with read#

read waits for a line of text and stores it in a variable. -p prints a prompt:

Terminal
cat > greet.sh <<'EOF'
#!/bin/bash
read -p "What is your name? " name
echo "Welcome, $name!"
EOF
chmod +x greet.sh
echo "Ravi" | ./greet.sh
Output
Welcome, Ravi!

We piped in the answer here. In a terminal, you would type it. read -s hides typing, which suits passwords.

A useful example#

This script reports the state of a machine:

Terminal
cat > status.sh <<'EOF'
#!/bin/bash
echo "Host:   $(hostname)"
echo "User:   $(whoami)"
echo "Disk:   $(df -h / | awk 'NR == 2 {print $5}') used"
echo "Files:  $(ls -A ~ | wc -l) in home"
EOF
chmod +x status.sh
./status.sh
Output
Host:   laviyx
User:   asha
Disk:   83% used
Files:  6 in home

Printing with printf#

echo is fine for simple text. printf gives exact control over the format:

Terminal
printf "%-8s %5s\n" "Item" "Price"
printf "%-8s %5d\n" "Tea" 20
printf "%.2f\n" 3.14159
Output
Item     Price
Tea         20
3.14

Here documents#

A here document feeds several lines to a command. With unquoted EOF, variables are expanded; with quoted 'EOF', the text is kept exactly:

Terminal
name=Asha
cat <<EOF
Dear $name,
Your report is ready.
EOF
cat <<'EOF'
Literal: $name
EOF
Output
Dear Asha,
Your report is ready.
Literal: $name

Bash or Python?#

Use Bash forUse Python for
Running commands in orderComplex logic
Gluing tools togetherData structures
Short automationAnything over about 100 lines
Server setupCalling APIs and parsing JSON

Debugging#

bash -x prints each command before it runs, which shows you what a script is doing:

Terminal
bash -x greet.sh < /dev/null
Output
+ read -p 'What is your name? ' name
+ echo 'Welcome, !'
Welcome, !

Common mistakes#

Practice#

Practice exercise

Write sysinfo.sh, which prints the kernel name, the number of CPU cores (nproc), and the current user, each on its own labelled line. Run it, but print only the first and last lines.

Show solution
Terminal
cat > sysinfo.sh <<'EOF'
#!/bin/bash
echo "Kernel: $(uname -s)"
echo "Cores:  $(nproc)"
echo "User:   $(whoami)"
EOF
chmod +x sysinfo.sh
./sysinfo.sh | sed -n '1p;$p'
Output
Kernel: Linux
User:   asha

Key takeaway#

Next: Variables and Quoting.

Finished this lesson?