Example of how to identify the user using a linux Bash script

Example of how to identify the user using a linux Bash script

It is often necessary to run commands with sudo in bash scripts or directly in the script itself, but this raises a series of problems.

For example, when using sudo, should the variable ~ or $HOME in the script, which refers to the user folder, point to my real user folder such as /home/pi, or to the super administrator's user folder /root/?

It actually points to the /root/ folder, which we definitely don’t want. But many commands, such as installing a program, have to use sudo, so what should I do?

First of all, let me share my experience: command line permission execution can be divided into the following five situations from the performance point of view:

  • admin-manual: ordinary users type commands manually
  • sudo-manual: manually type the command plus sudo
  • admin-bash: execute bash scripts as a normal user
  • sudo-bash: execute bash scripts with sudo
  • root-any: Log in as root user

Many variables and environment variables will often be confused in these 4 situations! (The chaos refers to us, not the computer)

Also, here’s a little tip.

We all know that the ~ variable refers to the current user's directory. In fact, a variable in the format of ~abc can point to the user directory of a specified user, such as ~pi will point to /home/pi, or ~ubuntu will point to /home/ubuntu.

Let’s clarify our thoughts:

There is no problem when executing scripts normally, such as ./test.sh. There is no problem even if sudo appears in the script, such as sudo apt-get update.
In other words, serious problems will only occur when sudo is executed on the entire script, such as sudo ./test.sh!

So suppose my real user is pi, and my HOME directory is /home/pi. Now I want to find the correct solution under the execution mode of sudo ./test.sh.
The following are the various statements and variables in the script and the displayed results:

# (Not recommended!)
$ whoami
>>> root

# Different from whoami, it can indicate which users are currently logged into the computer, including everyone logged in locally and through ssh. $ who am i
>>> Some machines show empty >>> Mac shows: pi ttys001 Nov 26 16:57

# Equivalent to whoami (not recommended!)
$ echo $USER
>>> root

# User home directory location (not reliable and not recommended!)
echo $HOME
>>> /root

$ User home directory location, equivalent to $HOME (not recommended!)
$ echo ~
>>> /root

# Use the environment variable LOGNAME directly
$ echo $LOGNAME
>>> root

# Explicitly call the environment variable LOGNAME 
$ printenv LOGNAME
>>> root


# SUDO_USER is an environment variable in root's ENV.
# At the same time, ordinary users do not have env, only root users can display it $ sudo echo $SUDO_USER
>>> pi


# Display the call environment variable SUDO_USER (not recommended!)
# From the results, you can see that even if the script is executed as sudo, it will be different if sudo is added to the script!
$ printenv SUDO_USER
>>> pi
$ sudo printenv SUDO_USER
>>> root

From the above test, we can see that if we use sudo to execute the bash script, many variables are "unreliable".

In Stackoverflow, the more consistent tendency is to use the $SUDO_USER environment variable. And in the test, it is indeed the most "stable", that is, it can be consistent under different permissions and OS systems (only for systems with sudo).

Now that we have the username, we can use a command like ~pi to get the home directory /home/pi, but!

Now the problem arises again: when typing manually, we can get the correct address of ~pi, but the script does not recognize what ~pi is. At most, it is a string, not a variable.

In this case, we can't use the ~abc method, but use the old-fashioned but definitely not confusing method:
Look directly from /etc/passwd.

Manually, you can directly open passwd to view it, but it is more troublesome in the script. The most convenient way is to use the system command getent, that is, Get Entries command, to obtain the information of the specified user:

$ getent passwd pi
>>> pi:x:1000:1000:,,,:/home/pi:/bin/bash

So, what's left is to take out /home/pi, which we can easily take out using cut.

So the whole process is as follows:

me=$SUDO_USER
myhome=`getent passwd $me | cut -d: -f 6`

Successfully got /home/pi!

Going a step further, what if the script is not run as sudo? At this time, there is no SUDO_USER variable in the environment variables of the root user and ordinary users. Then we need to add a step of judgment:

me=${SUDO_USER:-$LOGNAME}
myhome=`getent passwd $me | cut -d: -f 6`

That is, if SUDO_USER is empty, $LOGNAME is used normally to get the current user. Why not use $LOGNAME instead of $USER? Because USER is not available on every system, but LOGNAME is available on all *nix systems.

renew

Since some OS cannot correctly obtain LOGNAME, the uid method is used to obtain the user path:

HOUSE=`getent passwd ${SUDO_UID:-$(id -u)} | cut -d: -f 6`

Update again

MacOS does not have /etc/passwd and does not support the getent passwd <UID> method to obtain user information, but the contents of the $USER and $HOME variables can remain unchanged under sudo.

So change it to the following:

HOUSE=${$(`getent passwd ${SUDO_UID:-$(id -u)} | cut -d: -f 6`):-$HOME}

That is, if the getent method cannot obtain the content, the value of $HOME is directly obtained.

Update again

Because bash does not support the above nested ternary expression, it needs to be separated:

HOUSE="`cat /etc/passwd |grep ${SUDO_UID:-$(id -u)} | cut -d: -f 6`"
HOUSE=${HOUSE:-$HOME}

Update again and again

If it is root, grep uid will match all lines containing 0 in passwd, so it should be improved as follows:

HOUSE="`cat /etc/passwd |grep ^${SUDO_USER:-$(id -un)}: | cut -d: -f 6`"
HOUSE=${HOUSE:-$HOME}

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • Launch a Git-Bash window in a specific directory using a batch script
  • Detailed explanation of script debugging mechanism in bash
  • Handling variables with spaces in shell script (bash script)
  • Bash script enables you to view Linux system information every time you log in to the shell
  • How to Monitor Linux Memory Usage Using Bash Script
  • Detailed explanation of how to pass password to ssh/scp command in bash script
  • Detailed explanation of the differences between source, sh, bash, and ./ in shell script execution
  • Linux bash script monitoring start and stop weblogic service script writing
  • How to write secure, fully functional Bash scripts

<<:  React event mechanism source code analysis

>>:  mysql5.7.19 winx64 installation and configuration method graphic tutorial (win10)

Recommend

5 common scenarios and examples of JavaScript destructuring assignment

Table of contents Preface 1. Extract data 2. Alia...

How to check disk usage in Linux

1. Use the df command to view the overall disk us...

Detailed explanation of Nginx timeout configuration

I recently used nginx in a project, and used Java...

mysql query data for today, this week, this month, and last month

today select * from table name where to_days(time...

MySQL 8.0.12 installation and configuration method graphic tutorial (windows10)

This article records the installation graphic tut...

How to use the concat function in mysql

As shown below: //Query the year and month of the...

Bootstrap 3.0 study notes grid system case

Preface In the previous article, we mainly learne...

List rendering instructions for efficient development of Vue front-end

v-for directive Speaking of lists, we have to men...

Install Docker for Windows on Windows 10 Home Edition

0. Background Hardware: Xiaomi Notebook Air 13/In...

How to completely uninstall iis7 web and ftp services in win7

After I set up the PHP development environment on...

W3C Tutorial (3): W3C HTML Activities

HTML is a hybrid language used for publishing on ...

jQuery implements clicking left and right buttons to switch pictures

This article example shares the specific code of ...

JS quickly master ES6 class usage

1. How to construct? Let's review the common ...