Difference between shell and environment variables - linux

What are the differences between shell and environment variables?
Where are these variables stored?

Citing this source,
Standard UNIX variables are split into
two categories, environment variables
and shell variables. In broad terms,
shell variables apply only to the
current instance of the shell and are
used to set short-term working
conditions; environment variables have
a farther reaching significance, and
those set at login are valid for the
duration of the session. By
convention, environment variables have
UPPER CASE and shell variables have
lower case names.
To list all environment variables, use printenv and to list all shell variables, use set.
You'll note that the environment variables store more permanent value, e.g.:
HOME=/home/adam
Which changes quite seldom, while the shell variables stores local, temporary, shell-specific values, e.g.:
PWD=/tmp
which changes every time you change your current directory.
For most practical tasks, set environment values by adding export VARIABLE_NAME=VALUE to your ~/.bashrc file.

For Bash shell:
Shell variables differ from environment variables in different ways:
♦ A shell variable is specific to the shell itself and is not inherited by child processes. For example, let's say you're running another application from the shell, that application will not inherit the shell variable:
$ SHELL_VAR=xyz
$ firefox
SHELL_VAR will not be available in the environment of the child process (firefox).
♦ In contrast, environment variables of the parent process (the shell here) are inherited by all child processes:
$ export SHELL_VAR=xyz
$ firefox
♦ Both shell and environment variables are local to the shell/process which defined them:
Environment variables can be persistent, whereas, for shell variables once you exit the session, they're all gone.
Note: the above examples only alter the shell that you're working on, in other words, if you logout or start a new shell/terminal you're not going to see the variables that you defined, this is per the principle of process locality.
How to make presistent shell variables:
One way to do that is by modifying the ~/.profile file:
export SHELL_VAR=xyz
This setting is user-specific and not system-wide, for system-wide environment variables, you can add the above line to a .sh file in /etc/profile.d
I highly recommend reading this page: EnvironmentVariables

Their difference is similar to the difference between private fields and protected fields in a Java class.
The private fields of a Java class is only accessible from that Java class. The protected fields of a Java class is accessible from both that Java class and its subclasses.
The shell variables of a shell is only accessible from that shell process. The environment variables exported from that shell is accessible from both that shell process and the sub-processes created from that shell.

A shell variable is just a special case of an environment variable.
shell variables are inherited from the environment and possibly copied to the environment of children of the shell depending on syntax used:
http://www.pixelbeat.org/docs/env.html

Related

How to ADD an environment variable that can be used by other process in Linux?

In a graphical DE, like KDE, what command can be used to add a new environment variable that can be used by any other process?
Note:
1) I'm aware of export A=B, but it only works for subsequent processes started in the same shell that executed the export, processes started else where, like a graphical application such as Chrome, won't be aware of the export.
2) I'm also aware that you can put it into ~/.bash_profile or alike, but that would need a restart/relogin for the setting to take effect.
Is there something like export but have effect for all applications and doesn't require a significant restart?
Your assumption that you need to restart after placing a variable definition (whether through an export statement or otherwise) in ~/.bash_profile, is flawed. You only need to source the file again after making modifications:
source ~/.bash_profile
or the more portable version:
. ~/.bash_profile
Either statement will (re)load any definitions in that file into your current shell. Sourcing is not the same as executing the script: it will modify the environment in the calling shell itself, not a subshell running the script.
A file like ~/.bash_profile may have many other definitions and settings in it that will mess with the shell. It is better to create a small (temporary) snippet with just the variables you want, and source that instead, as #JeremiahMegel suggests.
If you want to change the environment for a single process you run from the command line, you can set the variables on the same command line:
VAR=value /usr/bin/gedit
This will run gedit with the environment variable VAR set to value, but only for that one child process.
Unfortunately, your desktop applications are a bit more static than that. Most of the graphical applications you see in the menus are probably going to be represented by .desktop files in a folder like /usr/share/applications. These files are run in an environment that has almost none of the variables you are expecting. They rely on absolute paths, and most of the configuration is done by pointing the .desktop file to a script that performs its own setup. You can modify some of these files on an individual basis if you absolutely have to, but I would not recommend doing that. If you do insist on messing around with the graphical apps on your desktop, I would recommend making a copy of the desktop files you plan to modify in to ~/.local/share/applications, or whatever the equivalent is on your system. Those files will override anything found in /usr/share/applications and will only affect you.

Difference between global and local environment variables in Linux? Usage and Example

Path is an environment variable but i don't know whether its' a global or local environment variable. I need example for global and local environment variables and their usage in reference to Linux.
Its a question from my paper and i didn't study global or local environment variables. However, I have gone through shell and environment variables. So, i guess one of them (shell and environment) is global and local.
Because you specifically referenced the PATH variable, I'm going to assume you're referring to variables that impact a user in terminal mode on Linux. Even so, these two terms can have various meanings.
An example:
Most linux distros will have a file called /etc/bashrc (or /etc/bash_profile, etc. depending on distro). This file will contain settings variables for the bash shell as determined by the system administrator. These are "global" or "environment" variables, and it includes the PATH variable, but it also sets things like whether or not some commands provide their output in color, what the shell prompt looks like, etc.
Some power-users will not be satisfied with these defaults, and want to change them. They can create a file called /home/poweruser/.bashrc, and inside they can override most if not all of the variables in /etc/bashrc. Another example of this would be creating a custom ~/.vimrc, or even setting variables temporarily on the command line like so:
$ LANG=utf8
$ echo $LANG
utf8
This link has more information on the differences between the two and how to look at what variables are set on your shell: http://howtolamp.com/articles/difference-between-local-and-environment-variables/

Does anybody know where is LD_PRELOAD variable, in which file?

Just as the title said, I don't know where does this variable locate. I just know how to change it by typing:
$ export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libXpm.so.4
Then is it possible to change it in its file?
LD_PRELOAD is an environment variable (part of the "environment" defined by the C library and Unix conventions). That specific variable tells the dynamic linker how to behave.
It is probably not set to anything by default. If you want to give it a default value every time you log in or start up a shell, you can put that export statement in your .profile or .bashrc file (or whatever the equivalent is for your shell of choice). There's probably also a place you could set it in /etc that would apply to all logins or shells started on your system (if you need it to be set for other users too).
If you only need to set it for a specific program though, that may be overkill. Instead, you might want to write a short shell script to set the environment variable up first, then launch the program. E.G.:
#!/bin/bash
export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libXpm.so.4
~/my_program_that_needs_a_special_library

Set variables versus env variables Linux(debian) Bash shell

When creating set variables, what is the advantage of adding them to environment? Both are lost at session termination. I know obviously I can add useful stuff to .bashrc that I would want to access via my user.
Just not sure what the advantages would be? how common practice is it? do I need to worry about it? I am talking real life administration uses.
It seems to me like set is a local variable within a class. ENV is obviously global. Maybe the only use is when traversing different shells? How practical is it?
Environment variables are inherited by any process invoked by your shell. That includes both sub-shells and any other commands you invoke.
(Non-environment) shell variables are not.
For example, $TERM needs to be exported, because commands you invoke from your shell (a text editor, a pager, anything that uses a full-screen text display) needs to know what kind of terminal you're using, so it can look up its capabilities in termcap or terminfo. $LANG and similar variables need to be exported so that commands know about the current locale. $PATH needs to be exported so that any commands you invoke can then invoke other commands.
$PS1, the shell prompt, does not need to be exported, because it's relevant only to the current shell (and is typically initialized for new shells).

BASH: difference between "export k=1" vs. "k=1"

I am going to write an script and It looks there is no difference between:
export k=1
and
k=1
Am I right?
export makes the variable available to subprocesses.
That is, if you spawn a new process from your script, the variable k won't be available to that subprocess unless you export it. Note that if you change this variable in the subprocess that change won't be visible in the parent process.
See section 3.2.3 of this doc for more detail.
I've created a simple script to show the difference:
$ cat script.sh
echo $answer
Let's test without export
$ answer=42
$ ./script.sh
$ . script.sh
42
The value is known only if using the same process to execute the script (that is, the same bash instance, using source / .)
Now, using export:
$ export answer=42
$ ./script.sh
42
$ . script.sh
42
The value is known to the subprocess.
Thus, if you want the value of a variable to be known by subprocesses then you should use export.
Every process, even on Windows, has a block of memory known as the environment block, this contains environment variables. When a new process is created, by default, the environment block of the parent process is copied to the child, so environment variables are a simple way of passing text data to a child process.
The export command creates an environment variable, or converts an ordinary local variable into an environment variable. In the C-shell, one of its few redeeming features is that it uses a different syntax for environment variables (setenv) to local variables (set). Bourne shell derivatives, like Bash and Korn shell, hide all that.
Currently, only simple values can be passed, so items like arrays are not supported (it just exports the first element). Variable attributes, set using define, are also not exported unless the child process is a shell of the same type, i.e. another instance of bash. This also applies to exported functions, although it is possible to sometimes hack this between shells of different types (using eval).
In Bash (and others) there is a shell setting called allexport which means all variables are environment variables - probably a bad idea to se generally. You can supply a different environemnt block from languages like C using execve, but from the shell you need a program like env, see man env for details.

Resources