After bg %1 the job runs while the shell owns the terminal foreground. After fg %1 the running job owns the foreground. The terminal has one foreground group at a time.

Job control moves terminal foreground ownership between groups

Interactive job control lets a shell manage process groups that share a controlling terminal. The terminal has one foreground process group at a time, while other jobs can run or remain stopped in the background. Foreground ownership, running state, and the shell’s job table are distinct. A background job is not automatically suspended, and a stopped job has not necessarily terminated. ...

September 27, 2027 · 6 min · XB Field Notes
A parent with exported local creates two environment copies. Child A changes local to child; child B and the parent retain local. Arrows only point toward the children.

Environment variables are a per-process thing

An environment is a collection of name-value strings supplied to a program when it starts. A child normally receives the environment selected by its parent; changing that child’s copy does not rewrite the parent’s or a sibling’s copy. This is a useful configuration boundary, but it is not a promise that the command has no side effects. The program can still modify shared files, databases, or other resources using those settings. ...

September 25, 2027 · 5 min · XB Field Notes
One ./*.txt pattern becomes three separate Bash arguments, including ./two words.txt intact.

Bash globbing expands before the command runs

A wildcard in a Bash command usually becomes a list of pathnames before the target program starts. That makes *.txt convenient, but it also makes the command depend on the current directory and shell options. The program receives arguments, without information saying which ones came from a wildcard. Decide whether you intend to pass matching files or a pattern for the program to interpret. ...

September 8, 2027 · 4 min · XB Field Notes
For an external executable, the bare word tool takes an external lookup route to a file; ./tool follows a separate direct-path route to the named file.

A bare command the shell cannot find

“Command not found” identifies a lookup failure, but lookup does not always mean walking every directory in PATH. In ordinary Bash, a command word without a slash can resolve to a function, builtin, cached executable path, or a newly searched executable. An alias may already have changed the command while the input was read. Inspect the shell that actually reported the failure before reinstalling a tool that may already exist. ...

May 20, 2027 · 4 min · XB Field Notes
Four exact values retain four boundaries when forwarded with quoted dollar-at.

$@ and friends give a function its whole argument list

A wrapper should pass the arguments it received without changing their boundaries. In Bash, "$@" does that when used as command arguments: each positional parameter becomes a separate quoted word. This matters for empty values, spaces, newlines, and literal wildcard characters. A command that happens to work with two simple filenames can still be broken if its wrapper reconstructs the list as a single string. ...

April 16, 2027 · 4 min · XB Field Notes
The current-status lane starts with failed work returning 7 and later successful logging returning 0. An immediate capture branches down to a saved=7 lane that persists independently until explicit return or exit.

Exit status is a compact report of what went wrong

An exit status is a small value that a shell uses to decide what runs next. Zero means success for shell control flow; a nonzero status takes the failure branch. That does not give every number a universal application meaning. A search with no matches, invalid input, and an unavailable server may deserve different handling even though all can produce nonzero results. Read the command’s contract before deciding what to retry or ignore. ...

March 27, 2027 · 4 min · XB Field Notes
Inside one shared shell, a function gets its own positional list, shifts it, then returns to the unchanged caller list. Shared variables sit alongside those temporary argument frames.

A shell function reads its arguments like a script

A shell function groups commands under a name and receives its own positional arguments. In an ordinary call, its body runs in the current shell rather than automatically starting a separate process. That makes functions useful for reusable operations, but it also means assignments, directory changes, and other shell state can affect the caller. A function needs an explicit contract for inputs, output, status, and any intentional side effects. ...

March 16, 2027 · 5 min · XB Field Notes
A stdout tape containing first, an internal newline, second and two trailing newlines becomes captured text first newline second; the internal newline stays and both trailing newlines are removed.

Command substitution puts one command's output into another line

Command substitution captures a command’s standard output and inserts the resulting text into a surrounding expression. The familiar $(command) form is useful for a timestamp, a computed label, or another small textual value. It is not a transparent channel for arbitrary bytes or a reliable way to transport a list of filenames. Its newline handling, execution environment, and exit status are part of the interface you need to understand. ...

March 3, 2027 · 5 min · XB Field Notes