183

This is irritating me. I seen several suggestions (all using different files and syntax) and none of them worked.

How do I set an environment variable for a specific user? I am on debian squeeze. What is the exact syntax I should put in the file to make ABC = "123"?

  • 9
    What did you try already? – l0b0 Sep 28 '11 at 11:25
  • 2
    editing .bashrc, .bash_profile, .profile and .ssh/eviroment. Although i dont know if i wrote it in the right location or had the right syntax each time –  Sep 28 '11 at 11:33
  • 4
    .bashrc is the main place for that. – rozcietrzewiacz Sep 28 '11 at 11:58
  • @rozcietrzewiacz: ok but... even after having the solution i tried setting ABC1 and ABC2 at the start and end of that file and it isnt set in my environment. –  Sep 28 '11 at 12:31
  • 1
    Check that .bash_profile contains something like [[ -f ~/.bashrc ]] && . ~/.bashrc. – rozcietrzewiacz Sep 28 '11 at 12:38
  • what the heck!? i tried ssh-ing in and the variables i set in .bashrc show but not the ones in .bash_profile! ok, easy fix but... i dont understand why this is happening. –  Sep 28 '11 at 12:40
  • @rozcietrzewiacz: thanks. Somehow i notice that line adds in bashrc UNLESS i stick a new line (making it 2lines with the second one empty). I'm clueless but it works with one line so i am happy –  Sep 28 '11 at 12:47
  • This is not a full answer, but if it's shell-specific, I recommend putting it in .bashrc; if it's not, put it in .profile. I source .profile and .bashrc (in that order) from .bash_profile, and make sure to put [[ $- != *i* ]] && return on the top of .bashrc. – Alexia Luna Nov 06 '14 at 14:50
  • // , Any way to do this without putting the values in a disk file? – Nathan Basanese Jan 19 '19 at 05:33

6 Answers6

141

You have to put the declaration in the initialization files of your shell:

  • If you are using bash, ash, ksh or some other Bourne-style shell, you can add

    ABC="123"; export ABC
    

    in your .profile file (${HOME}/.profile). This is the default situation on most Unix installations, and in particular on Debian.

    If your login shell is bash, you can use .bash_profile (${HOME}/.bash_profile) or .bash_login instead.

    Note: If either of these files exists and your login shell is bash, .profile is not read when you log in over ssh or on a text console, but it might still be read instead of .bash_profile if you log in from the GUI. Also, if there is no .bash_profile, then use .bashrc.

  • If you've set zsh as your login shell, use ~/.zprofile instead of ~/.profile.

  • If you are using tcsh, add

    setenv ABC "123"
    

    in .login file (${HOME}/.login)

  • if you are using another shell look at the shell manual how to define environment variables and which files are executed at the shell startup.

Matteo
  • 9,796
  • 4
  • 51
  • 66
  • that was one of the things i tried. i stuck export ABC="123" at the end of ~/.profile right now, exit (to root) then su back into that user and it didnt work. I checked by writing env and echo $ABC -edit- i am using bash. But i think the shell is a softlink located at /bin/sh –  Sep 28 '11 at 11:20
  • 8
    The default behavior of su user is to change ownership of the current shell to the username arg, while keeping the home directory and environment of the calling user.

    To enter a shell in such a way as to become the new user, and gain all of their environmental settings ( $PATH, $HOME, $ABC, etc) you need to pass a - as the first argument to su.

    su - username will accomplish what you are asking for.

    – Tim Kennedy Sep 28 '11 at 11:35
  • 1
    Wait: what do you mean by "exited to root"? In any case making an 'su' does not initialize the shell. You need 'su -' (see man su) – Matteo Sep 28 '11 at 11:43
  • oh wow i didnt know that. Thanks @TimKennedy. However i still dont see the variable i set when using su - theuser :( –  Sep 28 '11 at 11:44
  • To check if your .bashrc (or .profile) is correct: source .bashrc. Is then the variable set? – Matteo Sep 28 '11 at 11:45
  • 1
    Why did you su in the first place? Didn't you just create a root-owned .profile that cannot be used by the user? – rozcietrzewiacz Sep 28 '11 at 11:50
  • @Matteo ?. It returns me nothing. No error, no msg, nothing. Although if i write export VAR="val" at the end of .bash_profile which i had to create and use su - user i do get results :D –  Sep 28 '11 at 11:51
  • 1
    @acid this is what is should have done. The question is, what is sourced when you log in. To check that, log out first. – rozcietrzewiacz Sep 28 '11 at 11:55
  • 9
    Because .profile is read by all Bourne-compatible shells, you should not write Bash syntax in that file. In particular, export VARIABLE=value needs to be refactored into VARIABLE=value; export VARIABLE. – tripleee Jun 06 '13 at 06:56
  • In Fedora: "/home/joshnoe/.profile: No such file or directory" – Josh Noe Sep 25 '17 at 23:11
  • 1
    @JoshNoe if it does not exist create it – Matteo Sep 26 '17 at 06:05
  • I use zsh. Will the .zprofile as describe above be read before .zshrc when login or when doing exec zsh? – Timo Dec 06 '17 at 15:54
  • export VARIABLE=value is perfecly fine in your .profile. It is recognized by all the Bourne-style shells mentioned by Matteo, as well as dash. The original Bourne shell itself may not accept this idiom, but why should you be limited in your scripts by the (lack of) features of a 45-year old program that you will not be using? (Nowadays /bin/sh is usually a symlink to either /bin/bash or /bin/dash, rather than the feature-poor Bourne shell.) – Silvio Levy Jan 17 '22 at 06:34
59

Use /etc/environment file for setting the environment variables. Then add the following line inside the /etc/environment file.

ABC="123"

Now the ABC variable will be accessible from all the user sessions. To test the variable output first refresh the environment variable using command

source /etc/environment

and run echo $ABC.

Bernhard
  • 12,272
Hokam
  • 691
  • 5
  • 3
  • 5
    Be careful that /etc/environment doesn't support the full bash syntax, something I figured out the hard way. For example, putting PATH="/usr/bin:/usr/sbin" and then doing PATH="$PATH:/foo/bar" on a following line won't work – user2428118 May 13 '16 at 14:20
  • Unsure if this is a personal issue or what, but I had to reboot my OS after setting this in /etc/environment, even if I restarted the bash terminal or typed source /etc/environment. So if you're having issues where the environment variable isn't perpetuating, try rebooting. – Blairg23 Jan 11 '18 at 01:04
  • 2
    The question is about setting it for a single user. I think /etc/environment is for all users on a machine. – Carolus Dec 30 '19 at 10:54
  • this one is the one that worked for me. many thanks! – falero80s Apr 18 '22 at 12:02
9

This is a general procedure you can use for pretty much any shell. In any case, you have to know which shell the user would normally log in with:

path="$(grep $USER /etc/passwd | cut -d ':' -f 7)"
shell="$(basename -- "$path")"

Then you have to figure out which dot-files this shell would normally read:

man $shell

A shortcut which might work is to list those dot-files which contain the shell name:

ls ~/.*${shell}*

If you want to check if one of the files is actually read during login, you can simply print the file name in each of them, for example:

echo .bashrc

When logging in, you should then see which files are being read, and you can decide which one to modify. Beware that you should not to try to use echo "$0" or similar, because the value of $0 depends on how the shell processes dot-files, and could be misleading.

When it comes to declaring the variable "permanently", note that this only extends to the session. There is no way to access the value of a variable without a session, so it has no meaning outside of one. If you mean "read-only", that is shell dependent, and in Bash you can use:

declare -r VAR

if it already has a value, or

declare -r VAR=value

to assign it at the same time. Not all shells have this feature.

To declare a variable in most shells, you should use a variable name ([A-Za-z_][A-Za-z0-9_]*), followed by an equal sign (and no spaces around the equal sign), then a value (preferably quoted unless the value is a simple [A-Za-z0-9_]+). For example:

name="John Doe"
ip=127.0.0.1
HORRIBLE=1
l0b0
  • 51,350
8

Use export.

export ABC="123"

To check if it's set, use

env

and/or

env | grep ABC

To add it permanently, add this to your ~/.bashrc file.

export ABC="123"
whoami
  • 3,870
2

Exact command is:

echo 'export ABC = "123"' >> ~/.profile
1

The best way that worked for me is modifying the .bashrc file in the BASH shell.

use this for example:

  1. open your .bashrc file
  2. add this line:

    export <VARIABLE> = "<ANY PATH/VALUE you want>"
    

    eg : export HOME = "/home/user/"

    Remember to use "" as using ' ' will not work and your bashrc file will report error while sourcing.

  3. source it in the current session.

I also tried to modify the /etc/environment file but it didn't allow me to create a new environment variable and when I sourced it, it prompted error that the defined variable is not found.