LearnLinux FoundationsBash Shell Environment

unset

unset - a hands-on Linux lab on a real virtual machine.

Make a shell variable truly disappear with unset. The plain form, -v for variables and -f for functions, and the distinction that trips everyone: name= leaves the variable existing but empty, while unset name removes it entirely. Both make echo print a blank line, so the screen cannot tell you which happened.

You have learned to make variables. name=alice and the shell remembers alice for you. You have learned to read them back with echo $name. But how do you make one go away?

Your first instinct is probably to blank it out: name=. That looks like erasing it. It is not. After name=, the shell still has a variable called name, it is just holding nothing. The name is still on the roster, sitting empty. This lesson is about the command that actually strikes the name off the roster entirely, so the shell forgets the variable ever existed. It is called unset.

The black boxes in this lesson are a practice terminal: a safe sandbox that checks the one command each step teaches, so you cannot break anything. Everything you unset here is a variable you set yourself moments earlier, so every result is exact and repeatable. Nothing touches your real machine.

unset removes a variable from the shell completely. Not blanked, not emptied: gone. After you unset a variable, asking for it gives you nothing back, because as far as the shell is concerned there is no such variable anymore.

Think of the shell's variables as names written on a whiteboard. Setting name=alice writes name on the board with alice next to it. Setting name= wipes out alice but leaves the word name still written there, waiting. unset name erases the whole line, the word name and all. The board no longer mentions it.

To see the difference you first need something to remove. Set a plain variable so you have a target. Type this:

name=alice

prompt: student@linuxcamp:~$ answer: name=alice output: hint: The name, an equals sign, then the value, no spaces around the equals: name=alice

Setting a variable prints nothing back, which is normal: the shell quietly filed alice under the name name. There is no output because assignment is silent. To prove the value is really there, you read it back next.

Before you remove anything, confirm the variable holds what you think. echo $name prints the value stored under name. The $ tells the shell to look up the variable and hand back its contents. Read it now:

echo $name

prompt: student@linuxcamp:~$ answer: echo $name output: alice hint: echo, a space, then a dollar sign stuck to the name: echo $name

There it is: alice. The variable exists and holds a value. Now watch what unset does to it. The syntax is as plain as it gets: the word unset, a space, and the name of the variable, with NO dollar sign. You write the bare name because you are naming the variable itself, not asking for its value.

Run the removal. Nothing dramatic prints, just like setting it printed nothing. But the variable is now gone from the shell:

unset name

prompt: student@linuxcamp:~$ answer: unset name output: hint: The word unset, a space, then the bare name with no dollar sign: unset name

Silent again, and that silence is success. unset does its work without comment. The proof that anything happened is in what you read back next: ask for name now and the shell has nothing to give you.

This is the heart of the lesson. Ask for the value again, exactly as before. The variable is gone, so echo prints a blank line and nothing else. That empty line IS the evidence that unset worked:

echo $name

prompt: student@linuxcamp:~$ answer: echo $name output:

hint: The same read as before, echo then dollar-name: echo $name

That blank line is not an error and not a bug. echo $name still ran fine; it simply had nothing to print, because name no longer exists. The shell does not warn you when you read a variable that is gone. It just hands back emptiness. This is the quiet trap of unset: remove a variable that something later depends on, and that later command sees an empty value with no complaint at all.

Here is the distinction most people get wrong. Both unset name and name= make echo $name print a blank line. They LOOK identical. They are not.

After name=, the variable still exists; it is just empty. After unset name, the variable does not exist at all. For everyday reading with echo you cannot tell them apart, because both give you nothing. The difference shows up when something checks whether the variable exists rather than what it holds. Set-but-empty passes an existence check; unset fails it.

You do not need a special test to feel the idea. Set the variable to empty and read it, and see that it behaves just like the removed one on the surface:

name=

prompt: student@linuxcamp:~$ answer: name= output: hint: The name and an equals sign, with nothing after it: name=

The shell just recreated name and set it to nothing. On screen echo $name would print the same blank line as the unset version, which is exactly why the two are so easy to confuse. But under the hood they are opposites: name= puts the name back ON the whiteboard holding an empty value, while unset name had rubbed the whole line OFF. Remember the rule this way: name= empties the box, unset name throws the box away.

Plain unset name works because the shell assumes you mean a variable. Two flags let you say exactly what you mean, which matters when a variable and a shell function share a name.

Most of the time you will type the plain form and never touch the flags. Reach for -v when you want to be explicit that you mean the variable, and -f when you have defined a shell function and want to remove the function rather than a variable of the same name. unset works the same on plain variables and on exported ones, so a value you sent into the environment with export comes out just as cleanly.

One real place unset earns its keep: clearing a secret. If you set an API token into your environment with export TOKEN=..., that value lingers for every program you launch. When you are done, unset TOKEN scrubs it from the environment so nothing else can read it. Removing a variable so a program falls back to its built-in default is the other everyday use.

Some variables are locked. If a variable was marked read-only, the shell refuses to let unset remove it, and it tells you so plainly. The literal message looks like this:

bash: unset: name: cannot unset: readonly variable

In plain words: the variable exists, but it has been frozen so it cannot be changed or removed. What to check first: whether the variable was declared read-only somewhere (often in a startup file with readonly name or declare -r name). A read-only variable cannot be unset for the life of that shell. That is by design; it protects values that are not meant to move.

Scaffolding off. No command is printed this time. You have every piece you need.

A variable called secret is sitting in your shell holding the word hunter2. You want it truly gone, not just blanked, so that the shell forgets it ever existed. Remove it.

prompt: student@linuxcamp:~$ answer: unset secret output: hint: The command that strikes a name off the roster, then the bare variable name, no dollar sign. Think unset, then secret.

That is the move. unset secret removed the variable outright, so it is gone rather than sitting empty. unset prints nothing on success, which is normal. If you now read it back with echo $secret you would get a blank line, because the shell has no such variable to hand you anymore. You recalled the command from memory, which is the same recall the real machine will ask of you.

You earned this cheat sheet. Every row is a form of unset you just reasoned through:

And the one distinction to keep for life: name= leaves the variable existing but empty, while unset name removes it so it does not exist at all. Both make echo $name print a blank line, so the screen cannot tell you which happened. Empty the box with name=; throw the box away with unset name.

If unset refuses with cannot unset: readonly variable, the variable was locked with readonly or declare -r. It stays for the life of that shell; open a fresh shell and it will not carry over unless a startup file sets it again.

The practice terminal has shown you the whole shape of unset: set a value, prove it is there, remove it, and read back the blank line that proves it is gone. You saw the contrast that trips everyone, name= empties while unset name deletes, and you met the read-only error and its one real fix. Every one of those you typed yourself.

The Bash Environment module ends with one real Linux machine, the bash environment capstone mission, and that is where you run unset for real alongside everything else in this module: making variables, exporting them, reading them back, and clearing them out. A VM boots just for you, with its own live shell. One difference from here: the mission shows no commands. You read the objective, you recall the command, you type it. That recall is what makes it stick.

Finish the other Bash Environment lessons, then go clear a variable for real.

Practice unset in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.