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

Introduction to the deletion process of B-tree

In the previous article https://www.jb51.net/arti...

The latest 36 high-quality free English fonts shared

01. Infinity Font Download 02. Banda Font Download...

React uses emotion to write CSS code

Table of contents Introduction: Installation of e...

Creative opening effect achieved by combining CSS 3.0 with video

Let me share with you a creative opening realized...

Differences and usage examples of for, for...in, for...of and forEach in JS

for loop Basic syntax format: for(initialize vari...

A complete tutorial on installing Ubuntu 20.04 using VMware virtual machine

Ubuntu is a relatively popular Linux desktop syst...

How to use limit_req_zone in Nginx to limit the access to the same IP

Nginx can use the limit_req_zone directive of the...

Let's talk about what JavaScript's URL object is

Table of contents Overview Hash Properties Host p...

Summary of the use of Datetime and Timestamp in MySQL

Table of contents 1. How to represent the current...

Display and hide HTML elements through display or visibility

Sometimes we need to control whether HTML elements...

Start a local Kubernetes environment using kind and Docker

introduce Have you ever spent a whole day trying ...

Teach you how to insert 1 million records into MySQL in 6 seconds

1. Idea It only took 6 seconds to insert 1,000,00...

Detailed examples of Zabbix remote command execution

Table of contents one. environment two. Precautio...

Circular progress bar implemented with CSS

Achieve results Implementation Code html <div ...

Use simple jQuery + CSS to create a custom a tag title tooltip

Introduction Use simple jQuery+CSS to create a cus...