本文介绍了在bash脚本中插值包含"$"的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个创建用户帐户的bash脚本.用户名和密码哈希值是根据某些条件从文件中提取的.密码哈希自然包含"$",用于限定哈希的字段(例如$ 1 $ {SALT} $ ...).

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

问题是, useradd 的-p选项要求在密码哈希中加上单引号,以防止将'$'字段内插为变量.传递变量时,为了正确地对其进行插值,引号必须为双引号.单引号将变量视为字符串.

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.

如何传递这样的值并确保它完全被内插而不被shell修改?

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}

扩展代码以获取更多上下文.

Expanded code for more context.

推荐答案

分配给 $ PASS 时,请使用单引号.双引号不会递归地扩展变量.

Use single quotes when you assign to $PASS. Double quotes won't recursively expand variables.

观察:

$ foo=hello
$ bar=world
$ single='$foo$bar'
$ double="$foo$bar"
$ echo "$single"
$foo$bar
$ echo "$double"
helloworld

引号仅影响外壳解析文本字符串的方式.当您完全不使用任何引号时,shell只会在变量内部"出现,即使那样,它也只会进行单词拆分和通配符扩展.

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.

这篇关于在bash脚本中插值包含"$"的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 18:21