LearnLinux FoundationsBash Shell Environment

export

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

Promote a private shell variable into the environment so child programs inherit it. Prove a plain variable is invisible to a child, then make it visible with export, fold both into export NAME=value, list exports with export -p, and un-export with export -n. Built from variables you set yourself, so the blank-line versus value contrast is byte-stable on every machine.

You set a variable in your shell. You typed the name, an equals sign, a value. It is right there. Then you run a program that asks for that exact variable, and the program comes back empty. Blank. As if you never set it.

You did nothing wrong. You just met the wall that sits between a variable in YOUR shell and the programs your shell launches. Most variables never cross it. This lesson is about the one command that opens a door in that wall, the command that turns a private note into a message every program you run can read. It is called export.

The black boxes in this lesson are a practice terminal: a safe sandbox that checks the one command each step teaches, so nothing you type can break anything. Almost everything here is built from variables you set yourself, so the outputs are the same on every machine. The single exception is marked where it appears.

When you set a variable the plain way, name=alice, it lives ONLY in your current shell. It is a private note to yourself. Programs your shell starts, called child processes because your shell launched them, never see it.

export changes that. It marks a variable for inheritance, so that every child process your shell launches gets its own copy. export name promotes name from a private shell note to an environment variable, one of the entries in that invisible list every program is handed at birth. That promotion is the whole job of export, and it is the machinery behind PATH, HOME, and every other setting programs rely on.

This split is as old as Unix itself. A process keeps two kinds of variables: private shell variables that stay put, and environment variables that get copied down to whatever it launches. export is the verb that moves a variable from the first pile to the second. It is why the environment env showed you in the last lesson is exactly the set of exported variables, no more, no less.

Before you can appreciate the door, you have to feel the wall. Set a plain variable, then ask a child program to print it.

bash -c '...' starts a brand-new shell as a child process and runs the quoted line inside it. So name=alice; bash -c 'echo $name' sets name in your shell, then launches a child and asks THAT child what name is. Before you run it, commit to an answer: does the child print alice, or a blank line?

name=alice; bash -c 'echo $name'

prompt: student@linuxcamp:~$ answer: name=alice; bash -c 'echo $name' output:

hint: Set the variable, a semicolon, then the child: name=alice; bash -c 'echo $name'

A blank line. The child printed nothing. You set name=alice a heartbeat earlier and it is genuinely there in YOUR shell, but the child process never received it. A plain assignment stays private to the shell that made it, so when the new bash looked up $name, it found nothing and echoed an empty line. That empty line is the wall. Now you open a door in it.

Same variable, same child, one word added. This time you export name before launching the child. That marks name for inheritance, so the child gets a copy. Then you run the exact same bash -c 'echo $name' as before.

Before you run it, commit to an answer: now that name is exported, what does the child print?

export name; bash -c 'echo $name'

prompt: student@linuxcamp:~$ answer: export name; bash -c 'echo $name' output: alice hint: Export the name you already set, a semicolon, then the same child: export name; bash -c 'echo $name'

This time the child said alice. Nothing about the value changed; name was alice before and after. What changed is that export name flipped it from private to inherited, so when your shell launched the child, it handed down a copy. The child looked up $name and, this time, found it. That is the entire mechanism of environment variables in one before-and-after: same variable, same child, and the only difference between a blank line and alice was the word export.

Setting a variable and then exporting it on a separate line works, but nobody does it that way in practice. export lets you do both at once. Write export NAME=value and it sets the variable AND marks it for inheritance in a single step.

This is the form you will type ninety-nine times out of a hundred. Do it in one line and confirm the child still sees it. Before you run it, commit to an answer: what does the child print?

export city=paris; bash -c 'echo $city'

prompt: student@linuxcamp:~$ answer: export city=paris; bash -c 'echo $city' output: paris hint: One export does both jobs: export city=paris; bash -c 'echo $city'

The child printed paris. export city=paris set city to paris and marked it for inheritance in the same breath, so the child launched with a copy already in hand. This one-line form is the everyday shape of export: whenever you want a setting to reach the programs you run, you set it and export it together, exactly like this.

Stop and look at what you can now do. You proved a plain variable is invisible to a child, then made it visible with a single word, then folded the whole thing into one line. That before-and-after, blank line versus alice, is not a trick. It is the exact reason PATH reaches every command, the reason a program you launch knows where HOME is, the reason config settings flow from your shell down into the tools you run. You now understand, from the ground up, how a variable becomes an environment variable. That is a genuine landmark in learning the shell.

How do you check what is already marked for inheritance? export -p lists every exported variable, one per line, each written as a declare -x NAME="value" line. The -x is bash's own shorthand for exported. Reading this list tells you exactly which variables your children will inherit.

export -p

prompt: student@linuxcamp:~$ answer: export -p output: declare -x HOME="/home/student" declare -x PATH="/usr/local/bin:/usr/bin:/bin" declare -x PWD="/home/student" declare -x USER="student" hint: Add the -p flag after export: export -p

That exact list belongs to the machine this was captured on. On YOUR machine the values will differ (a different HOME, a different PATH) and a real shell usually has many more declare -x lines than the four shown here. What stays the same everywhere is the SHAPE: one declare -x NAME="value" per line, and only variables that were exported appear. That shape is the lesson, not the specific values.

Sometimes you want to stop a variable being inherited but keep it around in your shell. export -n NAME does exactly that: n for no longer export. It un-exports the variable. The value stays set in your shell, but children stop receiving it, and it drops out of the export -p list.

So -n is the reverse of export: the door swings shut, the variable becomes a private shell note again, and the value is not lost, only the inheritance.

export -n NAME is not the same as unsetting a variable. unset NAME deletes it entirely, value and all. export -n NAME keeps the value in your shell and only removes the inheritance mark. Reach for -n when you want a variable to exist locally but not leak into the programs you launch.

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

You want a child program to see a variable named color with the value red. Set it and export it in a single line, then launch a child with bash -c 'echo $color' and have it print the value back. Build the whole line yourself.

prompt: student@linuxcamp:~$ answer: export color=red; bash -c 'echo $color' output: red hint: Use the one-line form from earlier. Think export color=red, a semicolon, then bash -c 'echo $color'.

The child printed red. You reached for the one-line form, export NAME=value, which set color to red and marked it for inheritance at once, then launched a child that inherited the copy and echoed it back. That is the same move that makes real environment variables work, built from memory. Recalling and typing it yourself is exactly what the real machine will ask of you.

Two things trip people up often enough to name.

The first is spaces around the equals sign. Just like a plain assignment, export allows no spaces around the =. Type it with spaces and bash reads the pieces as separate words.

export name = alice

prints:

bash: export: =': not a valid identifier`

That means bash saw name, then a lone =, then alice, three separate things, and none of them is a valid NAME=value pair. What to check first: remove every space around the equals sign. It must read export name=alice, tight, with nothing between the name, the =, and the value.

The second is a one-way street that surprises everyone. A child inherits a COPY of an exported variable, so a child can read it, and a child can even change its own copy, but that change never flows back up to the parent. If a child runs name=bob, the parent's name is still alice when the child finishes. Export sends values DOWN to children, never back UP to the shell that launched them. When you want a child's result back, the child has to print it and you capture the output; a changed variable alone will not travel upward.

You earned this cheat sheet. Every row is a form of export you just ran or met:

The one idea to carry out: a variable is invisible to the programs you run until you export it. export is the door between your private shell variables and the environment that every child process inherits. Set it, export it, and it reaches the tools you launch.

An export lasts only for the current shell and the children it launches. Close the terminal and it is gone. To make a variable export automatically every time you open a shell, you put the export line in a startup file called .bashrc. That file, and how the shell reads it at every login, is a lesson of its own coming later in this module.

The practice terminal has shown you the whole story of export. You saw a plain variable a child cannot see, the single word that lets the child see it, and the one-line form you will actually type. You listed what is exported, and you learned to un-export without losing the value. 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 use export for real. A VM boots just for you, with its own live environment full of variables you can set, export, and hand down to the programs you run. It hands you objectives that use exactly what you practiced across this module: variables, env, export, and the PATH they all flow through. 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 export a variable to a real program for yourself.

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