Overview
Most developers assume that the open square bracket [ used in Bash scripts is merely an opening punctuation mark for condition blocks. In reality, Unix-like systems treat [ as a standalone executable command. This guide explores the architectural reality behind the bracket command, how it evaluates expressions under the hood, and how to reliably inspect its results via process exit statuses ($?).
1. Unmasking the ‘[’ Executable and Locating Its Binary Path
Running which [ reveals the concrete filesystem location of the square bracket binary.
The system points directly to /usr/bin/[, proving that the character is not just shell punctuation but an actual program installed on disk.
⚙️ [Essential Evaluation Flags]
-f : Verifies whether the targeted path points to a regular file.-d : Validates whether the specified entry is a directory.-e : Checks for the physical existence of a file or directory path.-z : Returns true if the evaluated string has zero length (empty string).-n : Confirms that the target string is non-empty.= : Compares two strings for lexical equality.-eq : Assesses whether two integer operands are numerically equal.-ne : Assesses whether two integer operands are numerically unequal.

Executing type -a [ inspects the shell’s dispatch resolution chain for the [ symbol.
The shell outputs indicate that modern Bash prioritizes its internal built-in version (shell builtin) for performance reasons, while still preserving disk binaries at /usr/bin/[ and /bin/[.

Querying file metadata with ls -l /usr/bin/[ details the binary’s ownership and execution modes.
The listing highlights standard execution flags (-rwxr-xr-x), confirming that an authentic executable utility lives on the storage volume.

2. Basic Evaluation Syntax and Inspecting the Exit Status ($?)
Executing [ 10 -gt 5 ] evaluates whether integer 10 exceeds 5 using the -gt comparison flag.
The bracket command operates completely silently on standard output, delivering its computation purely through its process return code.

Running echo $? retrieves the exit code produced by the evaluation right before it.
A return value of 0 signals success, adhering to the Linux convention where zero represents a logical truth.

Running [ 10 -lt 5 ] tests whether 10 is strictly less than 5 using -lt.
As expected, the terminal prints no textual feedback, retaining the failure state exclusively in process memory.

Executing echo $? extracts the updated termination code from the failed test.
The resulting non-zero integer clearly flags a failed assertion, demonstrating how scripts branch based on these numeric signals.

3. Hands-On Filesystem Inspection (-f, -d, -s)
To set up an isolated sandbox for testing path-testing switches, initialize a fresh directory and empty file using mkdir -p /tmp/bracket_test && touch /tmp/bracket_test/sample.txt.

Executing [ -f /tmp/bracket_test/sample.txt ] && echo "파일이 정상적으로 존재합니다" confirms whether the target is an existing regular file.
Because the evaluation succeeds, the logical AND (&&) operator immediately triggers the subsequent confirmation string.

Running [ -d /tmp/bracket_test ] && echo "디렉터리가 맞습니다" validates that the given target is indeed a valid directory.
Meeting the criteria triggers a zero return code, allowing the chained print statement to run.

Executing [ -s /tmp/bracket_test/sample.txt ] || echo "파일 크기가 0(비어있음)입니다" tests whether the file has a payload size greater than zero bytes.
Since the newly touched file holds zero data, the condition fails, causing the fallback logical OR (||) branch to report the empty state.

4. Production Shell Scripting: Control Flow (if) and Clean-Up
To prepare meaningful content for conditional branching demonstrations, pipe test string data via echo "Ubuntu Shell Test" > /tmp/bracket_test/sample.txt.

Running if [ -s /tmp/bracket_test/sample.txt ]; then echo "내용 확인: $(cat /tmp/bracket_test/sample.txt)"; fi demonstrates how [ integrates smoothly within native Bash conditional control structures.
Detecting non-zero bytes via -s satisfies the guard statement, executing the inner block to display the file contents.

Tear down the temporary directory and test artifacts completely by executing rm -rf /tmp/bracket_test.

Understanding that [ behaves as an authentic command rather than arbitrary shell magic clarifies how Bash tests conditions and evaluates exit codes. Keeping these mechanics in mind will help prevent subtle scripting pitfalls and make shell logic far easier to debug.