Master Shell Scripting: Essential Tips and Tricks for Powerful Scripts
An in‑depth guide walks through the core concepts of Unix shell scripting, covering the purpose of a shell, prompt mechanics, echo usage, quoting rules, variable definition and export, exec versus source, grouping commands, parameter expansion, positional parameters, logical operators, I/O redirection, conditional statements, and loop constructs, all illustrated with clear examples.
1. Why Is It Called a Shell?
A shell is the user‑level interface to the operating system kernel. It acts as a command interpreter, translating user commands into actions performed by the kernel and returning the results back to the user. Common shells include sh, bash, csh, and ksh.
2. Shell Prompt (PS1) and Carriage Return (CR)
After logging into a shell, the prompt (e.g., $ for regular users, # for root) indicates that the shell is ready to accept a command. The command is executed only after the carriage‑return character (CR) is received.
3. The echo Command
echowrites its arguments to standard output (stdout). Useful options include: echo -n – suppress the trailing newline. echo -e – enable backslash‑escaped characters.
Standard streams:
stdin – standard input
stdout – standard output
stderr – standard error
4. Single vs. Double Quotes
Hard quote ( '...') – disables all variable and command expansion.
Soft quote ( "...") – allows variable expansion while preserving literal spaces.
5. Variable Assignment and export
Define a variable with name=value (no spaces around =). Access it via ${name}. Using export name=value makes the variable part of the environment, so child processes inherit it.
# Local variable
A=B
# Remove variable
unset A
# Environment variable
export A=B6. exec vs. source
source script.shruns the script in the current shell, allowing it to modify the current environment. exec ./script.sh replaces the current shell process with the script, so any changes to variables disappear after the script finishes.
# Create a subshell to run a script
./1.sh
# Run in current shell
source 1.sh
# Replace current shell
exec 1.sh7. Grouping with ( ) vs. { }
( )executes the grouped commands in a subshell, isolating variable changes. { } runs the commands in the current shell, so variable modifications persist.
8. Parameter Expansion: $(()) , $() , and ${}
$(())performs arithmetic expansion. $() captures the output of a command (command substitution). ${} provides powerful parameter expansion for strings, such as removing prefixes/suffixes, extracting substrings, and conditional defaults.
# Assume a variable
file=/dir1/dir2/dir3/my.file.txt
# Non‑greedy left delete
${file#*/} # dir1/dir2/dir3/my.file.txt
# Greedy left delete
${file##*/} # my.file.txt
# Greedy right delete
${file%%.*} # /dir1/dir2/dir3/my
# Substring extraction
${file:0:5} # /dir1
${file:5:5} # /dir2
# Replace first occurrence
${file/dir/path} # /path1/dir2/dir3/my.file.txt
# Replace all occurrences
${file//dir/path} # /path1/path2/path3/my.file.txt9. Positional Parameters: $@ vs. $*
$@expands to each quoted argument separately (e.g., "p1" "p2 p3" "p4"). $* expands to a single string containing all arguments separated by the first character of IFS (typically a space).
10. Logical Operators && and ||
cmd1 && cmd2runs cmd2 only if cmd1 succeeds (exit status 0). cmd1 || cmd2 runs cmd2 only if cmd1 fails (non‑zero exit status).
11. I/O Redirection: > and <
< fileredirects standard input from file. > file redirects standard output to file, overwriting it; >> file appends instead. Combining descriptors, e.g., 2>&1, merges stderr into stdout.
ls my.file no.such.file 1> file.out 2>file.err
# Merge stderr into stdout
ls my.file no.such.file 1> file.out 2>&1
# Discard output
ls my.file no.such.file >/dev/null 2>&112. Conditional Constructs: if vs. case
# if example
read YN
if [ "$YN" = Y ] || [ "$YN" = y ]; then
echo "continue"
else
exit 0
fi
# case example
read YN
case "$YN" in
[Yy]|[Yy][Ee][Ss]) echo "continue" ;;
*) exit 0 ;;
esac13. Loops: for , while , and until
# for loop
for ((i=1;i<=10;i++)); do
echo "num is $i"
done
# while loop
num=1
while [ "$num" -le 10 ]; do
echo "num is $num"
num=$((num+1))
done
# until loop
num=1
until [ "$num" -gt 10 ]; do
echo "num is $num"
num=$((num+1))
doneUse break to exit a loop, return to exit a function, and exit to terminate the script.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
