I'm trying to replicate the functionality of /etc/profile.d
by copying the segment of /etc/profile
that runs the scripts in profile.d
in my ~/.profile
, and have it run scripts under ~/.profile.d
.
Here's my ~/.profile
.
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.
# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
PATH="$HOME/.local/bin:$PATH"
fi
## Begin user section:
## Add $HOME/.profile.d
if [ -d "$HOME/.profile.d" ]; then
for i in '$HOME/.profile.d/*.sh'; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
Here's the golang.sh
mentioned in that error:
GOPATH=$(go env GOPATH)
export PATH=$GOPATH/bin:$PATH
unset GOPATH
I also copied lines 33-35 from my ~/.profile
into a separate script called test.sh
and ran that as i="$HOME/.profile.d/golang.sh
to confirm those lines do what I expect:
if [ -r $i ]; then
echo "Can read ${i}" # Prior line is checking if the script file can be read, so if it does echo it here.
. $i # this is what it originally did, sourcing the scripts inside a for loop.
fi
And, it does. I'm really confused. My understanding is the section I copied from /etc/profile
iterates over every file in the given path (/etc/profile.d
in the original, $HOME/.profile.d
in my version), and checks if it can read them, then sources them (which is distinct from running them normally) if it can.
I have since run this script through ShellCheck as recommended by the bash
tag, and it said to use single quotes in the for statement since double quotes break those. That fixed the error when logging into Cinnamon, but it still doesn't source the scripts in ~/.profile.d
like I was expecting it to.
As you may have gathered, I'm a shell scripting noob.
I should note golang.sh
has not been made executable. I don't think it needs to be, since it's being sourced and not executed, and /etc/profile.d
scripts don't have +x
set either. Also, doing . $HOME/.profile.d/golang.sh
or source $HOME/.profile.d/golang.sh
still sets my path like I expect.
Your for loop
for i in '$HOME/.profile.d/*.sh'; do
> echo "$i"
> done
produces
$HOME/.profile.d/*.sh
because you have single quotes, so it's not expanded.
Remove the single quotes. As mentioned by Toby Speight, you can double quote $HOME
(e.g. "$HOME"/.profile.d/*.sh
) to expand that part but not the rest of the expression.