11

What is the Linux equivalent of %username%?

I need to run a script on multiple Linux boxes every few days. I made a .sh file, and it works fine. The script deletes some files at a certain path. Problem is that the path includes the username (no, not in /home), which is different on each machine.

For now, I simply modified the script on each machine to match the username used there. But I want to have a script that will work, without needing to modify it.

So: does Linux have such functions? Duh, I'm sure it does, you noob....

Monty Harder
  • 297
  • 1
  • 6
Dr.Ping
  • 123
  • 1
    That depends, what does %username% mean? I guess it's some sort of Windows thing, but don't assume we'll know what it is. We're Linux people here, and most of us know very little about Windows. Please [edit] your question and explain what you need. – terdon Jul 25 '16 at 15:40
  • 1
    I've edited the title for this (pending peer review). You're not asking about a "wildcard"; %username% is a Windows environment_variable, and you're asking about the Linux equivalent, (which is also an environment variable). – Monty Harder Jul 25 '16 at 17:04
  • It'd be marvellous if you could accept whichever answer you found most helpful, to round of the Q&A format nicely. – Arronical Jul 26 '16 at 08:27
  • @Arronical true. Honestly, I didn't read any of the other answers and comments. I feel that everything added after your answer fails to realize the background to my question. Once the flood started, I didn't care about this thread anymore. I rarely interact with any of the SE sites (posts, answers or comments). About 90% of the times that I did, I hated what followed and disliked SE a little more. I like to read posts and discussions, but there's a certain square-headedness to SE overall, I feel. There are plenty of other highly professional forums that I like (Spiceworks, LinkedIn groups). – Dr.Ping Aug 04 '16 at 17:24
  • @Arronical I'm not trying to say that SE should change things. Evidently this system works great. – Dr.Ping Aug 04 '16 at 17:27
  • @Arronical when the comments started getting irrelevant, I wanted to delete the post. Unfortunately, that option doesn't exist here. – Dr.Ping Aug 04 '16 at 18:01
  • SE is definitely a very different format to a forum, it's one that I get along well with, as I like that any answers given are vetted by others through the voting process. Horses for courses really. It's certainly not perfect. In this case it's worth taking Keith Thompson's answer into account if you're running this script as a cron job. Cron doesn't use the same environment as an interactive session, or a script launched form a user's command line, so $USER won't necessarily work in that case. – Arronical Aug 05 '16 at 08:46

4 Answers4

17

The Linux version environment variable to refer to the current user is USER.

To get the output you'd like to see use $USER in your command:

echo $USER

And to use it in another string such as a path:

/path/with/$USER/in/it

Will expand the username within the string. Though you should protect variable expansions with curly braces when a variable is directly next to other characters. It's not so important in this example as the USER variable is bounded by non-alphanumeric characters, but would be important in the following case:

/path/to/${USER}directory

(Thanks to ByteCommander for the tip in comments)

Another useful one to know is $HOME for the user's home directory.

Arronical
  • 19,893
12
$USER

will change it into your username.

Example

rinzwind@schijfwereld:~$ echo $USER
rinzwind

There are more...

~$ cd /tmp
:/tmp$ echo $HOME
/home/rinzwind
:/tmp$ echo $PWD
/tmp
$ echo $HOSTNAME
schijfwereld

To list the current values of all environment variables:

env

Keep in mind that variable names are case-sensitive


To expand on this. You can create your own too:

export var=value

will create $var with value.

$ export var=1111
rinzwind@schijfwereld:~$ echo $var
1111
Rinzwind
  • 299,756
  • 7
    Case sensitivity is a very good point to raise with someone coming from an MS background. – Arronical Jul 25 '16 at 15:29
  • 3
    Note that export is only necessary if you want child processes to also see the variable and its value. If it's only being used in the current process a simple assignment is sufficient. Also, you should quote variables when they are evaluated: echo "$var" – Dennis Williamson Jul 25 '16 at 20:34
9

There might be a caveat if you plan to read the $USER environment variable in a command starting with sudo.

Bash variable expansion takes place before executing sudo to switch users, that means the $USER variable gets read from the current environment before sudo switches to root.

$ echo $USER
bytecommander

$ sudo echo $USER
bytecommander

If this is not intended and you require a method that will return the name of the user as whom it really runs (normally "root"), you have at least three options to achieve that:

  • Run a bash interpreter as root and pass it the command which contains $USER. You must make sure that the command is enclosed with single quotes to prevent the current Bash interpreter from doing the variable expansion:

    sudo bash -c 'echo $USER'
    
  • Use a command output instead of the $USER environment variable.

    There are mainly two commands which would be useful here, whoami and id -un:

    $ whoami
    bytecommander
    
    $ sudo whoami
    root
    
    $ id -un
    bytecommander
    
    $ sudo id -un
    root
    

    More information about those commands can be found by typing man whoami and man id.

You can use these commands like a variable and embed them into a string (e.g. a directory path) like this, using Bash's command substitution syntax. Here are two examples which cd into a directory named after the current user:

cd /path/to/$(whoami)folder
cd /path/to/$(id -un)folder
Byte Commander
  • 107,489
  • Is whoami the exact same as id -un? – wjandrea Jul 25 '16 at 17:26
  • the end result is :P – Rinzwind Jul 25 '16 at 19:20
  • 3
    sudo echo $USER doesn't display bytecommander because sudo preserves environment variables -- in fact, sudo discards most environment variables that it has not been explicitly configured to keep. The reason sudo echo $USER displays bytecommander is that the variable substitution is performed by the shell before the result is passed to sudo; it's equivalent to sudo echo bytecommander in your case. Try sudo sh -c 'echo $USER' instead. – Stuart Olsen Jul 25 '16 at 20:20
  • @StuartOlsen Thank you very much for correcting my mistake, you're of course right. I observed this incorrectly. Would you mind reviewing my updated and corrected answer again? – Byte Commander Jul 25 '16 at 22:47
5

As the other answers say, $USER is usually set to the name of the current user account.

But at least on my system (Ubuntu 14.04) the $USER environment variable is not set for cron jobs. Instead, you can use $LOGNAME (POSIX), which is part of the environment for cron jobs.

According to the environ(7) man page (type man 7 environ or man environ.7 to read it), $USER is used by BSD-derived programs and $LOGNAME is used by System-V-derived programs. They should have the same value if they're both set. The existence of both is an historical accident. (There could be cases where $USER is set and $LOGNAME isn't, but I don't know of any.)

The environ man page also documents a number of other common environment variables. (It doesn't document all environment variables because it would be impossible to do so.)