Background
I'm writing some scripts for standing up WSL instances with regularity, due to accidentally ruining a previous install, and the painful process of getting it back to a workable state. As part of this, I'm learning a lot about how Unix is managed, since it differs greatly from Windows.
Question
Is there a convention for avoiding name collisions between built-ins/binaries and variables?
This question came to mind because of certain common words for binaries, like groups
and file
, and I was having to be careful in situations like for file in ~/.ssh
.
My Current Understanding
In some cases, it looks like all-lowercase names are the norm for binaries, sometimes kebab-case, and obviously you can't write kebab-case variables. I also don't normally see uppercase names used outside of things like $PATH
or $HOME
. That said, while those can be considered variables, they also follow the C convention of all-caps for runtime constants, since they are largely static. You can add things to $PATH
, but it usually handled by a start-up process, like ~/.bashrc
.
Example Code
# User Setup
## Perform setup for each user account provisioned (should only be one)
for USERHOME in /home/*; do
USER="$(basename "$USERHOME")"
# make directory for SSH keys
mkdir -p "$USERHOME/.ssh"
# make development directories
mkdir -p "$USERHOME/bitbucket" "$USERHOME/github" "$USERHOME/gitlab"
# Copy SSH keys from host machine into each user
for fp in /mnt/c/Users/some_user/.ssh/*; do
f="$USERHOME/.ssh/$(basename "$fp")"
# If the SSH file isn't found in the current user's $HOME/.ssh
if ! test -e "$f"; then
# Copy from host machine
cp "$fp" "$f"
fi
# test if no extension, which is common for private SSH keys
# The test compares target file with a substitution that returns everything after a period (commonly the extension)
# Note: Problem occurs due to directory (~/.ssh) containing period.
fname = $(basename "$f")
if test -f "$f" && test "$fname" = "${fname#*.}"; then
# Private keys shouldn't be available to other users
chmod 600 "$f"
else
# Other files (like public keys) can be read-only to all users
chmod 644 "$f"
fi
done
# Add ssh-agent start command, and add SSH keys
if ! grep -q "ssh-agent" "$USERHOME/.bashrc"; then
tee -a "$USERHOME/.bashrc" <<- EOF > /dev/null
# Note: ssh-agent process count will include grep scan. Check for only one for not-started
if test \$(ps -ef | grep -c "ssh-agent") -eq 1; then
eval "\$(ssh-agent -s)"
elif test -z $SSH_AGENT_PID; then
export SSH_AUTH_SOCK=$(ls -1 /tmp/ssh-*/agent.* | head -n1)
export SSH_AGENT_PID="${SSH_AUTH_SOCK#*.}"
fi
if test \$(ls ~/.ssh/*_ed25519 2>/dev/null); then
ssh-add ~/.ssh/*_ed25519
fi
if test \$(ls ~/.ssh/*_rsa 2>/dev/null); then
ssh-add ~/.ssh/*_rsa
fi
EOF
fi
# Add current user to Docker permissions group
if test $(groups $USER | grep -c "docker") -eq 0; then
usermod -aG docker "$USER"
fi
if test -d /root/.cargo; then
cp /root/.cargo "$USERHOME"
echo '. "$HOME/.cargo/env"' >> "$USERHOME/.bashrc"
fi
# Switch ownership of the user's HOME to current user (defaults to root)
chown -fR "$USER" "$USERHOME"
done