A script
A Bash script is a plain text file of commands. Bash runs them top to bottom, as if you typed each one. This script, count.sh, counts the .txt files in a folder. Make it runnable once with chmod +x count.sh.
Type ./count.sh. Your shell asks the kernel to run the file. The kernel reads line 1, the shebang: #! then a path. So it starts /bin/bash, a new Bash process, and hands it the script.
Line by line
Line 2, count=0, makes a variable: a name that holds a value. Bash keeps it in its own memory. No spaces around the =, or Bash would try to run a command called count.
Line 3 starts a for loop. First Bash expands *.txt: it asks the kernel for the folder's names and keeps those ending in .txt, sorted: notes.txt and todo.txt. hello.py does not match.
Each pass puts the next name in f. First f is notes.txt. Line 4 does arithmetic: $((count + 1)) works out 0 + 1, and count now holds 1.
Line 5, echo "found $f", prints a line. Bash swaps $f for its value first, so the terminal shows found notes.txt. The double quotes keep the name in one piece, even if it had spaces.
done on line 6 sends Bash back to line 3 for the next name. Now f is todo.txt, count goes from 1 to 2, and echo prints found todo.txt.
No names are left, so the loop ends at done and Bash moves on to line 7. echo "$count text files" puts in the value of count, and the terminal shows 2 text files.
The end
At the end of the file Bash exits, and its variables go with it. It reports an exit status: 0 means success, any other number means failure. echo $? shows the last status: 0.
What happens
;; step 1/9 · script count.sh a text file, 7 lines bash runs the lines top to bottom make it runnable (once): $ chmod +x count.sh add execute permission then run it: $ ./count.sh
Some scripts start with #!/usr/bin/env bash instead, which finds bash wherever it is installed. You can also run a script without chmod +x by typing bash count.sh. Bash sorts the names a glob expands to using your locale's order. If no file matches, the pattern stays as it is (the loop would see the text *.txt) unless you turn on shopt -s nullglob.