🧠 SemiSimTech Intuition Lab

Shell Scripting Intuition

From running commands to building reliable Linux tools: shebang, variables, command substitution, quoting, arguments, and wrapper patterns.

Seed Example
linuxcmd wrapper
Core Theme
Shell as glue, Python as engine
Main Skills
Path safety, quoting, arguments
Learning Goal
Build portable command-line tools

πŸ“š Navigation

🧩 Big Picture

This lab turns a small real wrapper script into a full shell-scripting mental model. The main idea is that shell scripting is often not about writing a large program. It is about building a reliable interface that connects commands, files, paths, and user input.

Shell wrapper Python engine Path safety Quoting Arguments
Seed script
#!/bin/sh
# Convenience wrapper for Linux command helper.
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
python3 "$SCRIPT_DIR/linux_cmd_tool_v2_1.py" quick "$@"
Master frame

🧭 Shell scripting intuition: shell is glue, not the engine

Core idea

A shell script is a small automation layer that connects commands together.

Think:
β€’ Shell = glue / interface / orchestration
β€’ Python = logic / data processing / engine
β€’ Filesystem = where tools and data live

QuestionShell conceptExample
Who runs this script?Shebang#!/bin/sh
Where is this script located?$0 + dirname + pwdSCRIPT_DIR=...
How do I store a value?Variable assignmentSCRIPT_DIR="..."
How do I run a command and capture output?Command substitution$(pwd)
How do I pass user input forward?Arguments"$@"
How do I avoid path bugs?Absolute path from script directorypython3 "$SCRIPT_DIR/tool.py"
SemiSimTech tool pattern

User types a simple command β†’ shell wrapper receives it β†’ Python tool processes it β†’ output helps your work.

This is exactly how a personal CLI system starts.

Example

🧩 The seed wrapper script

linuxcmd wrapper
#!/bin/sh
# Convenience wrapper for Linux command helper.
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
python3 "$SCRIPT_DIR/linux_cmd_tool_v2_1.py" quick "$@"
What it does in one sentence

It lets you type:

linuxcmd usb

and internally translates it into:

python3 /path/to/linux_cmd_tool_v2_1.py quick usb

Concept 1

πŸ”‘ Shebang: choose the interpreter

Line 1
#!/bin/sh
Meaning

This tells Linux:

β€œRun this file using /bin/sh.”

Without it, the script may run under whatever shell called it, which is less predictable.

ChoiceMeaningUse case
#!/bin/shPOSIX shell, portableCompany Linux, simple wrappers
#!/bin/bashBash shell, more featuresWhen you need bash-only syntax
#!/usr/bin/env python3Run Python from PATHPython scripts
DSE rule

For portable company scripts, start with #!/bin/sh unless you really need bash features.

Concept 2

πŸ’¬ Comments: write intent for future you

Line 2
# Convenience wrapper for Linux command helper.
Meaning

Lines starting with # are comments. They are ignored by the shell.

Good comments explain why the script exists, not just what each command does.

Concept 3

πŸ“¦ Variables: store computed values

Variable assignment
SCRIPT_DIR="..."
Shell variable rules

Shell variables are simple strings.

Important:
β€’ No spaces around =
β€’ Use quotes around values
β€’ Read the value with $SCRIPT_DIR

CorrectWrongWhy
SCRIPT_DIR="/usr/local/bin"SCRIPT_DIR = "/usr/local/bin"Spaces around = break assignment
echo "$SCRIPT_DIR"echo $SCRIPT_DIRUnquoted version can break on spaces
python3 "$SCRIPT_DIR/tool.py"python3 $SCRIPT_DIR/tool.pyQuoted version is safer
Concept 4

πŸ” Command substitution: run a command and capture output

Pattern
VALUE="$(command)"
Meaning

$(...) means:

1) run the command inside
2) capture its printed output
3) store/use that output as text

Simple example
CURRENT_DIR="$(pwd)"
echo "$CURRENT_DIR"
Why quotes matter

Always prefer:

VALUE="$(command)"

instead of:

VALUE=$(command)

The quoted version is safer if output contains spaces.

Concept 5

πŸ“ Location-safe script: find where the script lives

The full line
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
PieceMeaning
$0Path used to call the script
dirname -- "$0"Extract directory part of the script path
cd -- "$(dirname -- "$0")"Move into the script directory
pwdPrint the absolute path
CDPATH=Disable CDPATH side effects so cd behaves predictably
&&Only run pwd if cd succeeded
Final meaning

Compute the absolute directory where this wrapper script lives, then store it in SCRIPT_DIR.

Why this is professional

Without SCRIPT_DIR, the wrapper may only work if you run it from the same directory.

With SCRIPT_DIR, the wrapper works from anywhere.

Deep dive

🧬 $0 and dirname: from script path to folder path

If user runs$0 may bedirname -- "$0" gives
./linuxcmd./linuxcmd.
/usr/local/bin/linuxcmd/usr/local/bin/linuxcmd/usr/local/bin
../tools/linuxcmd../tools/linuxcmd../tools
Intuition

$0 tells you how the script was called.

dirname extracts the folder from that path.

cd + pwd converts that folder into an absolute location.

Robustness

πŸ›‘οΈ Why CDPATH= is included

The piece
CDPATH= cd -- "$(dirname -- "$0")"
Meaning

CDPATH is an environment variable that can change how cd searches for directories.

Setting CDPATH= only for this command disables that behavior.

Why it matters

This avoids surprising output or wrong directory resolution on systems where CDPATH is configured.

It is a small detail, but it makes the wrapper more reliable.

Robustness

🧷 Why dirname -- and cd -- are used

Pattern
dirname -- "$0"
cd -- "some/path"
Meaning

-- means:

β€œStop parsing options after this point.”

This protects commands if a filename begins with a dash, such as -test.

Concept 6

πŸ’¬ Quoting: the most important shell scripting habit

Main rule

If a variable contains a path or user input, quote it.

Use:
"$SCRIPT_DIR"
"$0"
"$@"

UnquotedQuotedWhy quoted is safer
$SCRIPT_DIR"$SCRIPT_DIR"Preserves spaces in paths
$0"$0"Preserves script path as one argument
$@"$@"Preserves each user argument separately
$(pwd)"$(pwd)"Preserves command output as one string
Concept 7

πŸ“¨ Arguments: $@ forwards what the user typed

The piece
"$@"
Meaning

"$@" means:

Pass every argument exactly as received.

If user types:
linuxcmd previous directory

then "$@" forwards:
"previous" "directory"

VariableMeaning
$0Script name/path
$1First argument
$2Second argument
$#Number of arguments
$@All arguments
"$@"All arguments, safely preserved
Tool pattern

🐍 Shell wrapper + Python engine

Final line
python3 "$SCRIPT_DIR/linux_cmd_tool_v2_1.py" quick "$@"
PieceRole
python3Interpreter for the Python tool
"$SCRIPT_DIR/linux_cmd_tool_v2_1.py"Absolute path to the Python engine
quickSubcommand passed to Python
"$@"All user-provided search words
Transformation example

User types:
linuxcmd usb mount

Wrapper runs:
python3 /path/to/linux_cmd_tool_v2_1.py quick usb mount

Architecture insight

Shell wrapper = convenient command interface
Python script = real logic and data processing

Reusable template

🧰 Reusable shell wrapper template

Template
#!/bin/sh
# Wrapper for a local Python tool.
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
python3 "$SCRIPT_DIR/YOUR_TOOL.py" "$@"
How to reuse

Replace YOUR_TOOL.py with your Python script name.

If your Python tool needs a default subcommand, add it before "$@".

With default subcommand
python3 "$SCRIPT_DIR/YOUR_TOOL.py" quick "$@"
Debugging

⚠️ Common shell scripting mistakes

MistakeExampleFix
Spaces around =SCRIPT_DIR = valueSCRIPT_DIR=value
Not quoting variablespython3 $SCRIPT_DIR/tool.pypython3 "$SCRIPT_DIR/tool.py"
Using $@ unquoted$@"$@"
Assuming current directorypython3 tool.pypython3 "$SCRIPT_DIR/tool.py"
Using bash syntax in sh[[ "$x" == yes ]]Use [ "$x" = yes ] or change shebang to bash
No execute permission./linuxcmd gives permission deniedchmod +x linuxcmd
Debug habit

If a shell script fails, first print:

echo "$0"
echo "$SCRIPT_DIR"
echo "$@"

This reveals path and argument problems quickly.

Practice

πŸ‹οΈ Small practice exercises

Exercise 1 β€” Hello wrapper

Create hello.sh:

#!/bin/sh
echo "Hello from shell"

Then run:
chmod +x hello.sh
./hello.sh

Exercise 2 β€” Show arguments

Create args.sh:

#!/bin/sh
echo "script: $0"
echo "first : $1"
echo "all : $@"
echo "safe : $@"

Then run:
./args.sh previous directory

Exercise 3 β€” Location-safe wrapper

Create a script that prints its own directory:

#!/bin/sh
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
echo "$SCRIPT_DIR"

Run it from a different directory and confirm the output stays correct.

🧠 Flashcards

Click each card to reveal the answer. These preserve the original lab’s recall practice.

Q1. What does #!/bin/sh do?
It tells Linux to execute the script using /bin/sh.
Click to reveal / hide
Q2. What does $0 mean?
The path/name used to call the script.
Click to reveal / hide
Q3. What does dirname -- "$0" return?
The directory portion of the script path.
Click to reveal / hide
Q4. What does $(...) do?
Runs a command and captures its output.
Click to reveal / hide
Q5. Why use "$@"?
It forwards all user arguments while preserving argument boundaries.
Click to reveal / hide
Q6. Why use SCRIPT_DIR?
So the wrapper can find related files no matter where the user runs it from.
Click to reveal / hide
Q7. Why use CDPATH=?
To prevent CDPATH from changing cd behavior unexpectedly.
Click to reveal / hide
Q8. What does -- mean after a command?
Stop option parsing; treat later values as arguments/paths.
Click to reveal / hide
Q9. Shell vs Python role?
Shell is wrapper/glue/interface; Python is better for logic and data.
Click to reveal / hide
Q10. Most important shell habit?
Quote variables and user input: "$VAR", "$@".
Click to reveal / hide

πŸ“˜ Glossary

The original glossary is preserved below as quick reference vocabulary.

shebang

The first line like #!/bin/sh that selects the interpreter.

shell

Command interpreter that runs commands and scripts.

POSIX sh

Portable shell standard supported on many Unix/Linux systems.

variable

Named string value, e.g. SCRIPT_DIR="/path".

command substitution

$(command), which runs command and substitutes its output.

argument

Input word passed to a script or command.

$0

Script name/path used to call the script.

$@

All arguments passed to the script.

"$@"

All arguments safely preserved as separate arguments.

dirname

Command that extracts directory portion of a path.

CDPATH

Environment variable affecting cd search behavior.

wrapper

Small script that calls another tool with a simpler interface.

πŸš€ Final Insight

Shell scripting becomes powerful when it is treated as a tool-building layer.

The wrapper gives users a simple command. The shell handles location and arguments. Python performs the deeper logic. This is the core pattern behind many practical engineering tools.