Use $HOME, not /home/$USER in BASH scripts
Audience
This article is for experienced Linux users who are familar with environment variables such as
$HOME
and $USER
. These are the Linux users who are familiar with the
command line.
Problem and Solution
Here is an example not to use /home/$USER
:
[gpeddie-games@epcotcenter ~]$ su - gpadmin Password: mkdir: cannot create directory ‘/home/gpadmin’: Permission denied touch: cannot touch '/home/gpadmin/Templates/Text file': No such file or directory mkdir: cannot create directory ‘/home/gpadmin’: Permission denied -bash: /home/gpadmin/.local/share/DaVinciResolve/configs/.version: No such file or directory Welcome. All activities monitored at all times. Unauthorized access is strictly prohibited. gpadmin@epcotcenter ~ $
And here's the script (/etc/profile
) that illustrates an example:
# fix gnome missing 'New file' option if [ ! -f /home/$USER/Templates/"Text file" ] then mkdir -p /home/$USER/Templates touch /home/$USER/Templates/"Text file" fi # ... # this is a hack to bypass the Davinci Resolve new install Welcome/Onboarding screen since it does not render properly and is not required. if [ ! -f /home/$USER/.local/share/DaVinciResolve/configs/.version ];then mkdir -p /home/$USER/.local/share/DaVinciResolve/configs/ echo "Onboarding.Version=10" > /home/$USER/.local/share/DaVinciResolve/configs/.version fi
To fix this issue, simply replace all instances of /home/$USER
with $HOME
.
I am familiar with a text editor called Vim. It's a program that runs inside a terminal, similar to the
Command Prompt or PowerShell in Windows.
Before we proceed any further, let's create a backup copy of /etc/profile
:
sudo cp /etc/profile /etc/profile.bak
If anything goes wrong, you now have a backup. You can simply use the cp
(copy) command to
restore from the backup. Now let's begin.
First, open the Terminal (Konsole in KDE).
As root (or with sudo privileges), type the following command:
sudo vim /etc/profile
Type in the following command, starting with a colon:
:%s/\/home\/$USER/$HOME/g
The syntax for search and replace in Vim is as follows:
:%s/search/replace/g
Let's not concern ourselves with
g
at the end for now. Basically this command replaces "search" with the next text "replace." In other words, we want to replace/home/$USER
with$HOME
.Let's have a look at the script again:
# fix gnome missing 'New file' option if [ ! -f $HOME/Templates/"Text file" ] then mkdir -p $HOME/Templates touch $HOME/Templates/"Text file" fi # ... # this is a hack to bypass the Davinci Resolve new install Welcome/Onboarding screen since it does not render properly and is not required. if [ ! -f $HOME/.local/share/DaVinciResolve/configs/.version ];then mkdir -p $HOME/.local/share/DaVinciResolve/configs/ echo "Onboarding.Version=10" > $HOME/.local/share/DaVinciResolve/configs/.version fi
So why would we want to replace
/home/$USER
with$HOME
? That/home/$USER
should still work!Let's look at the output again after we save the changes.
Save the changes to the
/etc/profile
file.:wq
A
:
begins a command.w
writes changes to the file andq
quits VimIf you don't want to make changes to the file, then all you have to do is type
:q!
to exit without saving any changes.
As I mentioned, let's look at the output again when I log into my administrator account from a user account.
[gpeddie-games@epcotcenter ~]$ su - gpadmin Password: mkdir: cannot create directory ‘/home/gpadmin’: Permission denied touch: cannot touch '/home/gpadmin/Templates/Text file': No such file or directory mkdir: cannot create directory ‘/home/gpadmin’: Permission denied -bash: /home/gpadmin/.local/share/DaVinciResolve/configs/.version: No such file or directory Welcome. All activities monitored at all times. Unauthorized access is strictly prohibited. gpadmin@epcotcenter ~ $
Now, let's see the new output when I log back in as an administrator.
[gpeddie-games@epcotcenter ~]$ su - gpadmin Password: Last login: Sat Mar 18 11:13:52 EDT 2023 on pts/0 Welcome. All activities monitored at all times. Unauthorized access is strictly prohibited. gpadmin@epcotcenter ~ $
How Did That Work?
Let's see the output of $USER
and $HOME
.
gpadmin@epcotcenter ~ $ echo $USER gpadmin gpadmin@epcotcenter ~ $ echo $HOME /home/graysonpeddie.lan/gpadmin gpadmin@epcotcenter ~ $
Scenario
You have an Active Directory server running in a Windows Server virtual machine. You installed Nobara so that you can do content creation and play games. You wanted to join your Linux desktop to a Windows Active Directory in your home network (or a homelab, if you want to call it). This is how you install the needed packages for Nobara 36 (that's what I am running) so that you can join your Linux desktop to the Windows domain:
sudo dnf install realmd sssd sssd-tools adcli oddjob oddjob-mkhomedi sudo realm join yourlocaldomainname.lan -U youradminusername
Replace yourlocaldomainname.lan
with your local domain name and do the same for
youradminusername
.
So when you log into your administrator account that's part of the Domain Administrators so that you can gain sudo privileges, you might be wondering why you are getting strange output. Here it is again.
[gpeddie-games@epcotcenter ~]$ su - gpadmin Password: mkdir: cannot create directory ‘/home/gpadmin’: Permission denied touch: cannot touch '/home/gpadmin/Templates/Text file': No such file or directory mkdir: cannot create directory ‘/home/gpadmin’: Permission denied -bash: /home/gpadmin/.local/share/DaVinciResolve/configs/.version: No such file or directory Welcome. All activities monitored at all times. Unauthorized access is strictly prohibited. gpadmin@epcotcenter ~ $
If you look at the /etc/profile script that Linux executes when you log into your Linux account, you
will notice that the developer of Nobara assumed that your home directory is /home/gpadmin
and not /home/graysonpeddie.lan/gpadmin
.
This is how I configure the System Security Services Daemon (SSSD, for short) which allows Linux users
to log into the Windows domain from the Linux desktop. Please note that only root
can read
/etc/sssd/sssd.conf
.
[sssd] domains = graysonpeddie.lan config_file_version = 2 services = nss, pam [domain/graysonpeddie.lan] default_shell = /bin/bash krb5_store_password_if_offline = True cache_credentials = True krb5_realm = GRAYSONPEDDIE.LAN realmd_tags = manages-system joined-with-adcli id_provider = ad fallback_homedir = /home/%d/%u ad_domain = graysonpeddie.lan use_fully_qualified_names = False ldap_id_mapping = True access_provider = ad ad_gpo_access_control = permissive
Let's ignore the entire file and focus in the fallback_homedir
. The %d
is
for the domain name that I logged into and the %u
is for the username. In my case, since
I logged into my Linux desktop as gpeddie-games
(that's my account designed only for
gaming), my full path is /home/graysonpeddie.lan/gpeddie-games
and not
/home/gpeddie-games
.
I have all my users (only me) in a separate home folder in order to prevent any kind of conflict with
local user accounts, but then I still append my local admin account with -local
in order
to prevent any kind of conflicts in my Linux desktop machine.
Conclusion
This is why you should never assume that all users will be in the parent folder of the home directory.
The only use-case for using a $USER
environment variable is if you need to get the name of
the user. Referring back to the /etc/profile
script, here is an example:
if [ -x /usr/bin/id ]; then if [ -z "$EUID" ]; then # ksh workaround EUID=`/usr/bin/id -u` UID=`/usr/bin/id -ru` fi USER="`/usr/bin/id -un`" LOGNAME=$USER MAIL="/var/spool/mail/$USER" fi
After reading the script, I'm not sure why $LOGNAME
and $MAIL
exists in
that profile. Plus, I checked to see if I can get the name of the $USER
in my VPS server
and there is already a $USER
in the list of environment variables even though it's not
listed in /etc/profile
. Strange...
Anyway, I hope I can be of help and use to the people within the Linux community and I am hoping that people can learn from mistakes when getting the user's current home directory.
Article published: 2023-03-18 15:37
Categories: The World of Computers, Computers, Information Technology, Scripting and Programming,