set vs env vs export / which vs type / Quoting

3/2/20262 min read

1. set vs env vs export
  1. set: Shows everything (local variables, environment variables, and functions).

  2. env: Shows only environment variables (the ones passed to child processes).

  3. export: Takes a local variable and turns it into an environment variable so other programs can see it.

  4. unset NAME: Deletes the variable.

2. which vs type
1. The pwd and cd Mystery

"which" finds a physical file at /bin/pwd and /bin/cd. However, "type" correctly identifies them as shell builtins.

Why do both exist?

  • The Builtin: For performance and functionality. cd must be a builtin because a external program cannot change the directory of the shell that launched it.

  • The External File (/bin/pwd): These exist mainly for POSIX compliance and for when you want to use these commands outside of a shell (like in a restricted environment or a specific script that doesn't use Bash).

2. The Conflict

When you type "pwd" in your terminal, the shell has a choice. It checks its internal list of builtins first. Since pwd is there, it uses the builtin and ignores the file in /bin/pwd entirely.

  • type tells you what the shell will actually do (it uses the builtin).

  • which simply tells you "If I had to find a file on the disk with this name, here is where it is."

Note: So which command is more reliable for determining how a command is interpreted? The answer is always type. "which" can be misleading because it only searches the $PATH on the disk, ignoring the shell's internal logic. If you ask which command to use to identify a builtin, "type" is the answer.

3. Quoting

There are three main types of quoting:

1. Double Quotes (" ") - "Weak" Quoting

Double quotes allow the shell to interpret some special characters while treating others as literal text.

  • What stays special: Symbols like $ (variables) and ` (backticks/command substitution) still work.

  • What becomes literal: Spaces and wildcards (like * or ?) lose their special meaning.

  • Example:

NAME="Linux"

echo "Hello $NAME" # Output: Hello Linux (Variable expanded)

echo "Cost is $10.00" # Output: Cost is .00 (Wait! Bash thought $1 was a variable)

2. Single Quotes (' ') - "Strong" Quoting

Single quotes are the most restrictive. They treat every character inside them as a literal string. Nothing is expanded.

  • What stays special: Nothing.

  • Example:

NAME="Linux" echo 'Hello $NAME' # Output: Hello $NAME (Literal text, no expansion)

3. The Backslash (\) - Character Escaping

The backslash is used to quote a single character immediately following it. It is often called an "escape" character.

  • Example:

echo The cost is \$10.00 # Output: The cost is $10.00

Note:

Any time you use a pattern that contains wildcards (*, ?) or regex symbols (^, $, []) in a command like find, grep, or sed, always wrap the pattern in quotes.

  • If you want the Shell to expand the wildcard (like ls *.txt), leave it unquoted.

  • If you want the command (like find) to handle the wildcard, quote it so the Shell ignores it.

A Quick Test

If you are in a directory containing:

  • report1.txt

  • report2.txt

And you run this command: find . -name report*.txt (No quotes!)

What will the command actually run? (Hint: Does the shell expand report*.txt into report1.txt report2.txt before find sees it?)

You should always write it like this:

find . -name "report*.txt" (With quotes)

More on how to use find.