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

How to deploy Go web applications using Docker

Table of contents Why do we need Docker? Docker d...

Detailed explanation of daily_routine example code in Linux

First look at the example code: #/bin/bash cal da...

MySQL database constraints and data table design principles

Table of contents 1. Database constraints 1.1 Int...

JavaScript deshaking and throttling examples

Table of contents Stabilization Throttling: Anti-...

How to install redis in docker and set password and connect

Redis is a distributed cache service. Caching is ...

Bootstrap 3.0 study notes buttons and drop-down menus

The previous article was a simple review of the B...

How to create, start, and stop a Docker container

1. A container is an independently running applic...

How to set the page you are viewing to not allow Baidu to save its snapshot

Today, when I searched for a page on Baidu, becaus...

Summary of related functions for Mysql query JSON results

The JSON format field is a new attribute added in...

In-depth understanding of JavaScript callback functions

Table of contents Preface Quick Review: JavaScrip...

About using Alibaba's iconfont vector icon in Vue

There are many import methods on the Internet, an...

Understanding of CSS selector weight (personal test)

Copy code The code is as follows: <style type=...

Vue.js front-end web page pop-up asynchronous behavior example analysis

Table of contents 1. Preface 2. Find two pop-up c...