在 bash 脚本中插入包含“$”的变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19780286/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Interpolating variables which contain '$' in a bash script
提问by theillien
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}$...).
我正在编写一个创建用户帐户的 bash 脚本。用户名和密码哈希是根据特定标准从文件中提取的。密码散列自然包含分隔散列字段的“$”(例如,$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.
问题是 -p 选项useradd
需要在密码散列周围加上单引号,以防止将 '$' 字段插入为变量。传递变量时,为了正确插入它,引号需要加倍。单引号将变量视为字符串。
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?
我怎样才能传递这样一个值并确保它被完全插入并且没有被 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 }')
# 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.
编辑:扩展代码以获得更多上下文。
回答by Eevee
Use single quotes when you assignto $PASS
. Double quotes won't recursively expand variables.
分配给时使用单引号$PASS
。双引号不会递归扩展变量。
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.
引号仅影响 shell 解析文字字符串的方式。只有当您根本不使用任何引号时,shell 才会看起来“在”变量中,即使这样,它也只进行分词和通配符扩展。