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.
$_ (dollar underscore) is another special bash parameter and used to reference the absolute file name of the shell or bash script which is being executed as specified in the argument list. This bash parameter is also used to hold the name of mail file while checking emails.
bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.
This is a pattern match on the value of the first argument ( ${1} ) of your function or script. Its syntax is ${variable#glob} where. variable is any bash variable. glob is any glob pattern (subject to pathname expansion) to match against)
$$ is a Bash internal variable that contains the Process ID (PID) of the shell running your script. Sometimes the $$ variable gets confused with the variable $BASHPID that contains the PID of the current Bash shell.
Use single quotes when you assign to $PASS
. Double quotes won't recursively expand variables.
Observe:
$ foo=hello
$ bar=world
$ single='$foo$bar'
$ double="$foo$bar"
$ echo "$single"
$foo$bar
$ echo "$double"
helloworld
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With