Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interpolating variables which contain '$' in a bash script

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.

like image 393
theillien Avatar asked Nov 05 '13 01:11

theillien


People also ask

What does $_ mean in bash?

$_ (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.

What is $@ in bash?

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.

What does ${ 1 mean in bash script?

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)

What is $$ variable in bash?

$$ 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.


1 Answers

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.

like image 67
Eevee Avatar answered Sep 21 '22 17:09

Eevee