aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Tools & DevOps

Writing a Bash Script: A Practical Start to Automation

A bash script is the most practical way to take the commands you type one by one in the terminal and run them all at once from a single file. Doing repetitive jobs by hand — cleaning logs on a server, taking backups, deploying a project, or renaming dozens of files — is both tedious and a source of mistakes. In this article you will learn to write small but genuinely useful automations using the core building blocks: variables, conditionals, and loops.

Your first script: the shebang and execute permission

Everything starts with a file. Create a hello.sh and put a shebang on the first line. This line tells the system which interpreter should run the file:

#!/usr/bin/env bash
echo "Hello, automation!"

You then need to make the file executable, grant it permission, and call the script:

chmod +x hello.sh
./hello.sh

Using #!/usr/bin/env bash finds the correct interpreter without hard-coding where bash happens to be installed. Don't forget that first line; otherwise the script falls back to whatever shell happens to invoke it.

Variables and user input

When you define a variable there must be no spaces around the equals sign. To read the value you prefix it with $ and almost always wrap it in double quotes:

#!/usr/bin/env bash
name="Aslain"
echo "Welcome, $name"

# Reading input from the user
read -r -p "What is your name? " answer
echo "Hi $answer"

The double quotes matter: writing "$file" prevents file names that contain spaces from being split apart. Leaving them off ($file) is a classic source of bugs. To capture command output into a variable, use $(...):

today="$(date +%Y-%m-%d)"
echo "Today's date: $today"

Conditionals: if, test, and comparisons

Automation is incomplete without "do this in that case" logic. In bash you build conditions with if and square brackets. For numeric comparisons use -eq, -gt, -lt; for strings use = and !=:

#!/usr/bin/env bash
read -r -p "Enter a number: " n

if [ "$n" -gt 10 ]; then
  echo "$n is greater than ten"
elif [ "$n" -eq 10 ]; then
  echo "Exactly ten"
else
  echo "$n is less than ten"
fi

File and directory checks are the backbone of everyday scripts: -f asks whether a file exists, -d whether a directory exists, and -z whether a variable is empty:

if [ -d "/var/backups" ]; then
  echo "Backup directory is ready"
else
  mkdir -p /var/backups
fi

Loops: processing many files

Loops are where bash saves the most time. To iterate over the files in a folder you use for:

#!/usr/bin/env bash
for file in *.log; do
  echo "Processing: $file"
  gzip "$file"
done

You can also give it a numeric range to repeat a fixed number of times. When you want to loop until a condition is met, reach for while:

# From 1 to 5
for i in {1..5}; do
  echo "Attempt $i"
done

# Reading a file line by line
while IFS= read -r line; do
  echo "Line: $line"
done < list.txt

The IFS= read -r pattern is the safe way to read lines: it preserves leading and trailing whitespace and does not mangle backslashes.

Functions and arguments

As a script grows, turning repeated parts into functions improves readability. You access arguments passed to the script with $1, $2, and all of them at once with $@:

#!/usr/bin/env bash
log() {
  echo "[$(date +%H:%M:%S)] $1"
}

backup() {
  local source="$1"
  local target="$2"
  cp -r "$source" "$target" && log "Backed up: $target"
}

backup "$1" "/var/backups"

Using local inside a function confines variables to that function, so you don't accidentally clobber the rest of the script.

Robust scripts: error handling

Professional scripts don't quietly produce wrong results. Adding this line near the top should become a habit:

set -euo pipefail

These three settings work together: -e stops the script when a command fails, -u treats the use of an undefined variable as an error, and pipefail catches a failure in any command of a pipeline. Running your script through a static analysis tool such as ShellCheck before shipping it also catches quoting and variable mistakes early.

Frequently Asked Questions

What is the difference between bash and sh?

sh refers to the older, more limited POSIX shell; bash is a superset that offers arrays, [[ ]] tests, and richer syntax. If your script starts with #!/usr/bin/env bash, you can use bash features with confidence.

How do I debug my script?

The quickest method is to run it with bash -x script.sh, which prints each command before it executes. Alternatively you can put set -x inside the script and turn it off with set +x, tracing only the suspicious section.

Is bash enough for large automations?

Bash is excellent for file operations and chaining commands. But when you need complex data structures, JSON processing, or heavy logic, moving to a language like Python is more maintainable. A good rule of thumb: if you pass 100 lines with lots of branching logic, consider switching languages.

If you want to automate repetitive work but aren't sure where to start, from server scripts to deploy pipelines, get in touch with me for a practical setup.

Bu kategorideki tüm yazılar →

Devamı için