To set variable only for current shell:
VARNAME="my value"
To set it for current shell and all processes started from current shell:
export VARNAME="my value" # shorter, less portable version
To set it permanently for all future bash sessions add such line to your .bashrc file in your $HOME directory.
To set it permanently, and system wide (all users, all processes) add set variable in /etc/environment:
sudo -H gedit /etc/environment
This file only accepts variable assignments like:
VARNAME="my value"
Do not use the export keyword here.
Use source ~/.bashrc in your terminal for the changes to take place immediately.
To set variable only for current shell:
VARNAME="my value"
To set it for current shell and all processes started from current shell:
export VARNAME="my value" # shorter, less portable version
To set it permanently for all future bash sessions add such line to your .bashrc file in your $HOME directory.
To set it permanently, and system wide (all users, all processes) add set variable in /etc/environment:
sudo -H gedit /etc/environment
This file only accepts variable assignments like:
VARNAME="my value"
Do not use the export keyword here.
Use source ~/.bashrc in your terminal for the changes to take place immediately.
To set an environment variable once, use the export command in the prompt, not in a shell script:
$ export THEVAR=/example
The variable will be set for the rest of the shell session or until unset.
To set an environment variable everytime, use the export command in the .bashrc file (or the appropriate initialization file for your shell).
To set an environment variable from a script, use the export command in the script, and then source the script. If you execute the script it will not work.
For an explanation of the difference between sourcing and executing see this answer:
- What is the difference between executing a Bash script vs sourcing it?
This is because the shell expands the variable in the command line before it actually runs the command and at that time the variable doesn't exist. If you use
TEST=foo; echo $TEST
it will work.
export will make the variable appear in the environment of subsequently executed commands (for on how this works in bash see help export). If you only need the variable to appear in the environment of one command, use what you have tried, i.e.:
TEST=foo your-application
The shell syntax describes this as being functionally equivalent to:
export TEST=foo
your-application
unset TEST
See the specification for details.
Interesting part is, that the export command switches the export flag for the variable name. Thus if you do:
unset TEST
export TEST
TEST="foo"
TEST will be exported even though it was not defined at the time when it was exported. However further unset should remove the export attribute from it.
I suspect you want to have shell variables to have a limited scope, rather than environment variables. Environment variables are a list of strings passed to commands when they are executed.
In
var=value echo whatever
You're passing the var=value string to the environment that echo receives. However, echo doesn't do anything with its environment list¹ and anyway in most shells, echo is built in and therefore not executed.
If you had written
var=value sh -c 'echo "$var"'
That would have been another matter. Here, we're passing var=value to the sh command, and sh does happen to use its environment. Shells convert each² of the variables they receive from their environment to a shell variable, so the var environment variable sh receives will be converted to a $var variable, and when it expands it in that echo command line, that will become echo value. Because the environment is by default inherited, echo will also receive var=value in its environment (or would if it were executed), but again, echo doesn't care about the environment.
Now, if as I suspect, what you want is to limit the scope of shell variables, there are several possible approaches.
Portably (Bourne and POSIX):
(var=value; echo "1: $var"); echo "2: $var"
The (...) above starts a sub-shell (a new shell process in most shells), so any variable declared there will only affect that sub-shell, so I'd expect the code above to output "1: value" and "2: " or "2: whatever-var-was-set-to-before".
With most Bourne-like shells (see List of shells that support `local` keyword for defining local variables), you can use functions and the "local" builtin:
f() {
local var
var=value
echo "1: $var"
}
f
echo "2: $var"
With zsh, you can use anonymous functions which like normal functions can have a local scope:
(){ local var=value; echo "1: $var"; }; echo "2: $var"
or:
function { local var=value; echo "1: $var"; }; echo "2: $var"
With bash and zsh (but not ash, pdksh or AT&T ksh), this trick also works:
var=value eval 'echo "1: $var"'; echo "2: $var"
A variant that works in a few more shells (dash, mksh, yash) but not zsh (unless in sh/ksh emulation):
var=value command eval 'echo "1: $var"'; echo "2: $var"
(using command in front of a special builtin (here eval) in POSIX shells removes their specialness (here that variables assignments in front of them remain in effect after they have returned))
With the fish shell, you can make variables local to a begin..end block:
begin
set -l var value
echo 1: $var
end
echo 2: $var
With mksh (and soon zsh), you can abuse the ${|cmd} construct which can also have a local scope making sure it expands to nothing by making sure you don't set $REPLY within:
${|local var=value; echo "$var"}; echo "$var"
¹ Stricktly speaking, that's not completely true. Several implementations will care about the localisation environment variables (LANG, LOCPATH, LC_*...), the GNU implementation cares about the POSIXLY_CORRECT environment variable (compare env echo --version with env POSIXLY_CORRECT=1 echo --version on a GNU system).
² well only (some of) the ones that are valid variable names in the syntax of the particular shell. For instance env ++=foo 1x=bar 3=qwe '#=rty' IFS=asd é=x sh -c 'shell code' will not create ++, 1x, 3, # shell variables as those are not valid variable names (though # and 3 are non-variable shell parameters), and don't import IFS from the environment as that would be source of security vulnerabilities; for é, YMMV.
Set environment variable for one command on command line
Setting an environment variable before a command in Bash is not working for the second command in a pipe - Stack Overflow
How can I set my environment variables permanently?
Would someone explain the environment variables like I'm a crayon eating five?
Videos
If you want to set a variable in your shell (as opposed to the superuser's):
- Make sure your
.bashrcexists
ls -A ~/.bashrc
- Add your variable at the bottom
export VARIABLE=value
- Save, then open a new terminal and verify the variable is set
$ echo $VARIABLE
value
Keep in mind this depends on your shell.
Solution: In order to export and keep environment variables persistent on linux you should export variables decelration into one of the following files: ~/.bash_profile / ~/. bash_login / ~/.profile.
When bash is invoked as an interactive/non-interactive login shell, it first reads and executes commands from the file /etc/profile (if exists) and after looks for these following files ( in that order and do the same) ~/.bash_profile, ~/. bash_login, ~/.profile.
Example: adding secret token into my user profile.
cat << End >> ~/.profile
export SECRET_TOKEN=abc123!@#
End
output:
echo $SECRET_TOKEN
abc123!@#
I'm transitioning to zsh after many years of bash use and have almost got everything working. The one pattern I can't figure out is how to temporarily set/override an environment variable.
Bash allows:
The environment for any simple command or function may be augmented temporarily by prefixing it with parameter assignments, as described above in PARAMETERS. These assignment statements affect only the environment seen by that command.
I have scripts with lines of this form, where the value of FOO is set just for the single execution but seems not supported by zsh:
FOO=bar command
A simple set/unset is fragile as any interruption of the contained command will forego the unset:
FOO=bar ; command ; unset FOO
The closest I've come is this, but I've not fully explored the implications of the subshell, especially related to traps:
(FOO=bar ; command)
I accept this may be an anti-pattern moving forward, but for now I'm just trying to get everything running again.
In bash you can set variables like this:
export CATALINA_HOME=/opt/catalina
most other shells follow this convention, but not all. You can set it permanently in ~/.profile for bash (and as before, other shells have other locations)
- https://help.ubuntu.com/community/EnvironmentVariables
- Where to declare environment variables?
To set permanent environment variables in latest Ubuntu versions (from 14.04 and above)
add the variables to /etc/environment. For that follow the below instructions,
Open the terminal and run
sudo -H gedit /etc/environment
the provide your password, then in the prompted text file
then add the variables like
ANT_HOME="/opt/ANT/"
Sample of the /etc/environment is given below
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
JAVA_HOME="/usr/lib/jvm/java-8-oracle/"
AXIS2_HOME="/opt/axis2-1.7.4/"
ANT_HOME="/opt/apache-ant-1.9.7/"
don't forget to logout and login again to enable the environment variables.
This is an excerpt from the Bash man page:
export [-fn] [name[=word]] ...
export -p
The supplied names are marked for automatic export to the environment of subsequently executed commands. If the -f option is given, the names refer to functions...
If you only need the variable in the current environment, it's not necessary to use export.
var=value
Edit:
Without export: current environment only. With export: current environment and child environments.
Here's a demonstration of the affect of export on availability of a variable in a child environment and that changes in the child environment don't affect the parent:
$ var1=123
$ export var2=456
$ echo "parent [$var1] [$var2] [$var3]"
parent [123] [456] []
$ var3=789 bash -c 'echo "child [$var1] [$var2] [$var3]"; var1=111; var2=222; var3=333; echo "child [$var1] [$var2] [$var3]"'
child [] [456] [789]
child [111] [222] [333]
$ echo "parent [$var1] [$var2] [$var3]"
parent [123] [456] []
After the first echo (echo "parent...") you see "123" and "456" because both var1 and var2 are active in the current environment. You don't see a value for var3 because it's not set yet.
After the line that starts "var3=..." you don't see a value for var1 because it wasn't exported. You do see a value for var2 because it was exported. You see a value for var3 because it was set for the child environment only.
(bash -c is equivalent to running a script with the contents of the argument to the -c option. A script or other executable or, in this case, the argument to bash -c becomes a child of the current environment which, as a result is, of course, the child's parent.)
In the "script" the values of the variable are changed. It now outputs those new values.
Once the "script" is finished, execution returns to the parent environment (the command line in this case). After the last echo, you see the original values because the changes made in the child environment do not affect the parent.
You say that
I am always using export command to set environment variable
By the way you worded that, it sounds like you are really trying to ask how do you make an environmental variable persists. To do that would require you to place your export VAR="foo" statement in your $HOME/.bash_profile file (if you are using bash). If you want that environmental variable to persist for all users but root, then add it to /etc/profile. If you want it added for the root user too, then set it in /root/.bash_profile .
This will work for all login shells where bash is the shell of choice. For non login shells, you need to use .bashrc. I have no insights to offer for other shells :D
FOO=bar bash -c 'somecommand someargs | somecommand2'
How about exporting the variable, but only inside the subshell?:
(export FOO=bar && somecommand someargs | somecommand2)
Keith has a point, to unconditionally execute the commands, do this:
(export FOO=bar; somecommand someargs | somecommand2)