I'm writing a bash script which creates a user account. The username and password hash are pulled from a file based on certain criteria. The password hash naturally contains '$' delimiting the hash's fields (eg. $1${SALT}$...).
The issue is that the -p option for useradd
requires single quotes around the password hash in order to prevent the '$' fields from being interpolated as variables. When passing a variable, in order to properly interpolate it, the quotes need to be double. Single quotes treat the variable as a string.
However, if I pass the variable in double quotes, the variable is expanded and each '$' is then treated as if it is a variable meaning the password is never properly set. What's worse, is that some variables have braces ('{' or '}') in them which further bungles things up.
How can I pass such a value and ensure it is interpolated completely and without modification by the shell?
An example of the specific line of code with all interpolated variables intact:
# Determine the customer we are dealing with by extracting the acryonym from the FQDN
CUSTACRO=$(${GREP} "HOST" ${NETCONF} | ${AWK} -F "." '{print $2}')
# Convert Customer acronym to all caps
UCUSTACRO=$(${ECHO} ${CUSTACRO} | ${TR} [:lower:] [:upper:])
# Pull the custadmin account and password string from the cust_admins.txt file
PASSSTRING=$(${GREP} ${CUSTACRO} ${SRCDIR}/cust_admins.txt)
# Split the $PASSSTRING into the custadmin and corresponding password
CUSTADMIN=$(${ECHO} ${PASSSTRING} | ${CUT} -d'=' -f1)
PASS=$(${ECHO} ${PASSSTRING} | ${CUT} -d'=' -f2)
# Create the custadmin account
${USERADD} -u 20000 -c "${UCUSTACRO} Delivery Admin" -p "${PASS}" -G custadmins ${CUSTADMIN}
EDIT: Expanded code for more context.
Use single quotes when you assign to
$PASS
. Double quotes won't recursively expand variables.Observe:
Quotes only affect how the shell parses a literal string. The only time the shell looks "inside" a variable is when you don't use any quotes at all, and even then it only does word-splitting and wildcard expansion.