将一个bash变量替换为另一个变量时,空格会被转义

时间:2010-06-23 00:13:29

标签: xcode bash shell

我在bash脚本中保留空格时遇到了麻烦:

CURRENT_YEAR=$(date "+%Y")
MESSAGE=$(eval echo "$(/usr/libexec/PlistBuddy -c "Print NSHumanReadableCopyright" Info.plist)")

/usr/libexec/PlistBuddy -c "Set NSHumanReadableCopyright $MESSAGE" ${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}

相关部分Info.plist:

<NSHumanReadableCopyright>Copyright © BEC, ${CURRENT_YEAR}\nAll rights reserved.</NSHumanReadableCopyright>

脚本从plist中读取一个值,然后将另一个变量(CURRENT_YEAR)替换为从plist中读取的值。

问题是MESSAGE中的新行导致了问题。如果我使用\n,则会显示“n”而不是新行。如果使用实际的新行字符,则命令失败,因为'All'被解释为新命令。

如何逃离新线路?有一个更好的方法吗?我的bash-foo很少。

更新 - 解决方案:

感谢您的帮助。解决方案是用引号疯狂。这是完成的结果:

CURRENT_YEAR="$(date "+%Y")"
MESSAGE_TEMPLATE="$(/usr/libexec/PlistBuddy -c "Print NSHumanReadableCopyright" Info.plist)"
MESSAGE=$(eval echo '"'"$MESSAGE_TEMPLATE"'"')
/usr/libexec/PlistBuddy -c "Set NSHumanReadableCopyright $MESSAGE"  ${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}

3 个答案:

答案 0 :(得分:1)

我没有看到PlistBuddy做得很好,知道这是不是问题,但你的代码闻起来:

CURRENT_YEAR=$(date "+%Y")
MESSAGE=$(eval echo ...)

应该是

CURRENT_YEAR="$(date "+%Y")"
MESSAGE="$(eval echo ...)"

(请注意$(...)附近的额外双引号。

幸运的是,这将解决问题,您可以将未转义的换行符放在文件中,而不会将All解释为命令。否则可能是PlistBuddy问题。

答案 1 :(得分:1)

你必须在字符串eval'周围得到双引号(因此它将替换${}表达式,但不将新行视为命令之间的分隔符)。这有点困难,因为没有干净的方法将双引号放在双引号字符串中;但你可以通过在双引号字符串周围加上单引号的双引号来做到这一点(哦,然后我总是在整个事情中加上双引号,即使我不知道这是真的有必要):

CURRENT_YEAR=$(date "+%Y")
MESSAGE="$(eval echo '"'"$(/usr/libexec/PlistBuddy -c "Print NSHumanReadableCopyright" Info.plist)"'"')"

(如果您在解析时遇到问题,'"'是双引号(受单引号保护以防止在eval获取之前对其进行评估),"$(...)"是PlistBuddy的结果(受双引号保护),然后'"'是另一个受保护的双引号。

之后我认为你的PlistBuddy Set命令可以正常工作,但我之前必须引用它的值,以防万一:

/usr/libexec/PlistBuddy -c "Set NSHumanReadableCopyright '${MESSAGE//\'/\'}'" ${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}

(在撤消任何嵌入的单引号之后,将单引号放在$ MESSAGE附近。)

答案 2 :(得分:0)

尝试在MESSAGE=$(eval echo...行之后添加此内容:

printf -v MESSAGE "%q" "$MESSAGE"

这会将$MESSAGE的值存储回自身,并使用\等字符进行转义。