متغيرات البيئة في الصدفة
في هذا الدرس 11 موضوعات
هذا الدرس متاح حاليًا باللغة الإنجليزية فقط، ولم تُنشر نسخته العربية بعد.
Lesson Overview
In Module 5 you met PATH, an environment variable: a named piece of text that the operating system and your programs can read. You printed it and learned that a missing entry causes "command not found". You may have changed it through system settings.
This lesson looks at the same idea from inside the shell. You will read a variable, create your own, see exactly how long it lasts, and learn why a variable you set in one terminal is invisible in another. With the literal-assistant picture: an environment variable is a sticky note on the assistant's desk. Any program the assistant starts can read the note, but notes on one assistant's desk do not appear on another's.
This lesson builds on "Environment variables and PATH" in Module 5 and on the previous lessons of this module (running commands, quoting, and echo). You will use echo to print a variable, and you will run a command in a fresh child shell to prove what it can see.
The syntax is different in Bash and PowerShell, so every step is shown both ways. Where a feature depends on a version or system, the lesson says so.
Learning Objectives
By the end of this lesson you will be able to:
- Read an environment variable in Bash and in PowerShell.
- Set a variable for the current session in both shells.
- Explain what
exportadds in Bash. - List all variables and remove one.
- Explain why a variable disappears when the terminal closes.
- Add a folder to
PATHfor one session, without replacing the old value. - Name where permanent variables are usually stored, and why secrets should not live in code.
Written Explanation
Recap: what an environment variable is
An environment variable is a name and a text value, such as COURSE with the value java. Microsoft's PowerShell documentation describes them as always strings, and as inherited by child processes: when a program starts another program, the child receives a copy of the parent's variables at that moment.
You do not have to remember the technical words. Remember the effect: set it in a terminal, and programs started from that terminal can see it.
Reading a variable
| Shell | Read variable COURSE | Read PATH |
|---|---|---|
| Bash | echo $COURSE | echo $PATH |
| PowerShell | $env:COURSE | $env:PATH |
In Bash, the $ in front of a name means "the value of". In PowerShell, $env: is the prefix for environment variables. If the variable does not exist, Bash prints an empty line and PowerShell prints nothing.
Variable names are case-sensitive in Bash and, according to Microsoft, in PowerShell on macOS and Linux, so PATH and path differ there. On Windows they do not. Convention uses capitals for environment variables, and you should too.
Setting a variable
Bash
$ export COURSE=java
$ echo $COURSE
javaRules: no spaces around =. export COURSE = java fails. Quote a value that contains spaces: export TITLE="Java for backend".
PowerShell
PS> $env:COURSE = "java"
PS> $env:COURSE
javaIn PowerShell, spaces around = are fine and quotes are normal.
What export does in Bash
In Bash, you can create a plain shell variable with COURSE=java (no export). Your shell can use it, but programs it starts will not see it. Adding export marks the variable to be passed on to child processes, making it an environment variable.
You can prove it with a child shell:
$ COURSE=java
$ bash -c 'echo "child sees: $COURSE"'
child sees:
$ export COURSE
$ bash -c 'echo "child sees: $COURSE"'
child sees: javaThe single quotes matter. They stop your current shell from expanding $COURSE itself, so the child does the reading. This behavior is long-standing Bash practice; the manual page I read mentions that export assigns an attribute to variables, but I did not verify the child-process detail in a source in this session, so try the demo on your own computer.
PowerShell has no separate step: $env:COURSE = "java" writes straight into the environment, so child programs started from that session see it. You can check with a child PowerShell (the program is pwsh for PowerShell 7 and powershell for Windows PowerShell):
PS> pwsh -NoProfile -Command '$env:COURSE'
javaSingle quotes keep $env:COURSE for the child to evaluate.
Listing and removing variables
- Bash:
printenvlists all environment variables.printenv COURSEprints one value.unset COURSEremoves the variable from the current shell. - PowerShell:
Get-ChildItem Env:lists them all, andGet-ChildItem Env:COURSEshows one. Remove one withRemove-Item Env:COURSE. Microsoft's page also says that from PowerShell 7.5 on, assigning$null($env:COURSE = $null) removes it.
Output can be long. Pipe it into a filter from Lesson 4: printenv | grep COURSE, or Get-ChildItem Env: | Select-String COURSE.
How long does it last?
Only until you close that terminal, or more exactly until that shell session ends. Microsoft's documentation states that changes you make in PowerShell affect only the current session. In both shells, a variable set this way is invisible in a different terminal window, and gone when you reopen.
The reason is that each shell has its own copy. A new terminal gets its variables fresh from the system and your configuration files, not from the terminal you closed.
Making a variable permanent
Do not do it yet, but know where it lives:
- Bash and zsh: a line such as
export COURSE=javain a startup file such as~/.bashrcor~/.zshrc. Microsoft's page mentions those two files for non-login shells. Which file applies depends on the shell and how it was started, so check your system's documentation. - Windows: the Environment Variables dialog (reached through the system settings), which stores a value for your user or for the whole machine. PowerShell can also write a user-level value with
[Environment]::SetEnvironmentVariable('COURSE','java','User'). Microsoft's page documents that method and the scopes. After a permanent change, open a new terminal to see it, exactly as in Module 5.
Adding a folder to PATH for one session
PATH is a list of folders separated by : in Bash and on macOS and Linux, and by ; on Windows (Microsoft's page confirms both). To add a folder without losing the existing ones, put the old value inside the new one:
$ export PATH="$HOME/tools:$PATH"
PS> $env:PATH += ";C:\Tools"The Bash line puts ~/tools first and keeps everything else. The PowerShell line appends C:\Tools to the end, as in Microsoft's own example; on macOS or Linux use : instead of ;. The classic error is replacing PATH (export PATH=$HOME/tools), which removes everything else. Almost every command then stops being found, until you close the terminal.
Quoting and expansion in Bash
echo "$COURSE"andecho $COURSEprint the value. Double quotes allow expansion.echo '$COURSE'prints the literal text$COURSE. Single quotes block expansion.
In PowerShell, double-quoted strings also expand variables ("Course: $env:COURSE"), and single-quoted strings do not.
Examples
Example 1: Set, read, remove (simple)
Bash:
$ export GREETING="hello there"
$ echo $GREETING
hello there
$ unset GREETING
$ echo $GREETINGPowerShell:
PS> $env:GREETING = "hello there"
PS> $env:GREETING
hello there
PS> Remove-Item Env:GREETING
PS> $env:GREETINGAfter removal there is nothing to print. The variable lived only in this one terminal, and now it is gone from it too.
Example 2: The vanished variable (practical)
You set $env:COURSE = "java" in one terminal and see it print java. You open a second terminal window and type $env:COURSE. It prints nothing.
Nothing is broken. The second window is a separate shell session with its own copy of the environment, built from the system settings, not from the first window. The same happens in Bash. To make a variable available everywhere, store it permanently, then open a new terminal.
Example 3: A safe PATH experiment (realistic)
Imagine a small program, hello.sh, in ~/tools. Typing hello.sh gives "command not found", because ~/tools is not on PATH.
$ export PATH="$HOME/tools:$PATH"
$ hello.shThe shell now searches ~/tools first. (If you get "Permission denied", Lesson 6 explains why.) Close the terminal and reopen it, and the line is no longer in effect. That temporary effect is what makes this safe for experiments. On Windows, the same idea is $env:PATH += ";C:\Tools"; a program in C:\Tools can then be run by name from that session.
Backend Insight
Backend programs read configuration from the environment. A service started on a server may find where its database is in a variable named like DATABASE_URL, and which mode it runs in (testing or production) in another. The same program, started with different variables, behaves differently with no code change. This is why the same build can run on a laptop and in production.
It also keeps secrets out of source code. Passwords and keys are set in the environment (or in a secrets system) rather than written into files that get shared with a team. Java programs can read environment variables too, which you will see later in your Java learning.
Be careful what you print. Running printenv in front of colleagues or pasting its output into a bug report can leak secrets.
Common Mistakes
Mistake 1: Spaces around = in Bash
- Incorrect:
export COURSE = java - Correct:
export COURSE=java
Mistake 2: Mixing the syntaxes
$env:COURSE is PowerShell only. In Bash it prints something odd or an empty line. export COURSE=java is Bash only, and PowerShell will report that export is not recognised.
Mistake 3: Expecting the variable in another terminal or after closing
A session variable lives and dies with that shell. For anything permanent, use a startup file or the system settings, then open a new terminal.
Mistake 4: Replacing PATH instead of adding to it
export PATH=$HOME/tools loses the old list. Always include the old value: export PATH="$HOME/tools:$PATH".
Exercises
Try each exercise yourself before opening the solutions.
Level A: Foundation
A1. Which command prints the variable LEVEL in Bash? Which in PowerShell?
أظهر الحل A1
A1. Bash: echo $LEVEL. PowerShell: $env:LEVEL.
A2. What does export add in Bash?
أظهر الحل A2
A2. It marks the variable to be passed to programs the shell starts (child processes), turning a plain shell variable into an environment variable.
A3. True or false: a variable set with $env:LEVEL = "beginner" is still there after you close the terminal. Why?
أظهر الحل A3
A3. False. A variable set in the shell lasts only for that session, and a new terminal starts without it.
Level B: Application
B1. In your own shell, set LEVEL to beginner, print it, and then remove it. Write each command and its output.
أظهر الحل B1
B1. Bash: export LEVEL=beginner, echo $LEVEL prints beginner, unset LEVEL, echo $LEVEL prints an empty line. PowerShell: $env:LEVEL = "beginner", $env:LEVEL prints beginner, Remove-Item Env:LEVEL, $env:LEVEL prints nothing.
B2. In Bash, show that a variable without export is not visible to a child shell, and that it is visible after export. Write the commands.
أظهر الحل B2
B2. LEVEL=beginner, then bash -c 'echo "child sees: $LEVEL"' prints an empty value. After export LEVEL, the same command prints child sees: beginner.
B3. Find which of these lines would break your session, and say why: export PATH="$HOME/bin:$PATH" and export PATH=$HOME/bin.
أظهر الحل B3
B3. The second line, export PATH=$HOME/bin, replaces the whole list so most commands are no longer found. The first line keeps the old list by including $PATH.
Level C: Challenge
C1. In PowerShell, set NAME to Ana Smith (with a space) and print Hello, Ana Smith using the variable inside a double-quoted string. Show the command.
أظهر الحل C1
C1. $env:NAME = "Ana Smith" then "Hello, $env:NAME". Double quotes expand the variable.
C2. A teammate sets DB_PASSWORD in their terminal, runs the service, and it works. Tomorrow it fails with "password not set". Explain why, and suggest two safer places to keep the setting.
أظهر الحل C2
C2. The variable lived only in yesterday's terminal session, which ended. Safer places: a startup file or system environment setting for their account (and a secrets tool for real production systems), rather than typing the secret by hand each time or putting it in code.
Mini Challenge
Create a tiny "shell notes" demonstration, in the shell you use:
- Set a variable
PROJECTto the name of a made-up project and print it. - Show it is visible to a child shell (
bash -cor the PowerShell child command). - Add a folder of your choice to
PATHfor the session, and printPATHto prove the folder is on it. - Close the terminal, open a new one, and show with a command that
PROJECTis gone.
Check your work: your PATH change added to the old list rather than replacing it, and you did not print any secret.
Summary & Next Lesson
Key takeaways
- An environment variable is a name and a text value that programs started from your shell can read.
- Bash: read with
$NAME, set withexport NAME=value. PowerShell: read and set with$env:NAME. - Session variables last only until that shell session ends, and are not shared with other terminals.
- Add to
PATH, never replace it. Permanent settings go in a startup file or the system settings. - Backend programs take configuration and secrets from the environment, so the same code runs in different places.
Next lesson
You can now read and set variables. The next lesson, "Permissions basics", explains why a script you wrote may refuse to run, and how a file's permissions decide what can be done with it.
Self-check
- What does
echo $COURSEprint ifCOURSEwas never set? - How do you set a variable in PowerShell?
- Does
export NAME=valuesurvive closing the terminal? - Why is
export PATH=/toolsdangerous? - Why do backend programs read configuration from environment variables?
أظهر الإجابات
- An empty line.
$env:NAME = "value".- No. It lasts only for that session.
- It replaces the existing list, so most commands can no longer be found.
- The same program can behave differently in each place without code changes, and secrets stay out of source files.
References
- Microsoft Learn, about_Environment_Variables. Supports:
$Env:reads and sets, variables are strings, inheritance by child processes, changes affecting only the current session,Remove-Item Env:and$null(PowerShell 7.5 and later) for removal,SetEnvironmentVariablewith scopes,PATHseparators on Windows and non-Windows,$Env:PATH += ';C:\Tools', case sensitivity on macOS and Linux, and~/.bashrcand~/.zshrcas shell startup files. - man7.org, bash(1) manual page. Supports:
exportassigns an attribute to variables,PATHis a colon-separated list of directories, and~expands to the home folder. - Not verified on an official page: that a non-exported Bash variable is invisible to child processes, the
printenv,unset, andbash -cbehaviors, which startup file applies in which situation, and that Java can read environment variables. The text marks the child-process detail as something to try yourself.
التطبيق
طبّق هذا الدرس بمختبر الوحدة وتمارينها واختبارها.
تعليم الدرس كمكتمل اختياري ويمكنك التراجع عنه في أي وقت. يبقى تقدمك محفوظًا في هذا المتصفح.