Xcode 将一个bash变量替换为另一个变量时的空格转义

Xcode 将一个bash变量替换为另一个变量时的空格转义,xcode,bash,shell,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_

在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>

我看不出什么
PlistBuddy
做得足够好,足以知道这是否是问题所在,但您的代码有异味:

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

CURRENT_YEAR="$(date "+%Y")"
MESSAGE="$(eval echo ...)"
(注意
$(…)
周围的额外双引号)


幸运的是,这将解决问题,您可以在文件中放置未替换的换行符,而不必将
All
解释为命令。否则它可能是一个
PlistBuddy
问题。

尝试在
消息=$(eval echo…
行之后添加此项:

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

这将使用诸如转义的
\
等字符将
$MESSAGE
的值存储回自身。

您必须在被
求值的字符串周围加上双引号(因此它将替换
${}
表达式,但不能将换行符视为命令之间的分隔符)。这有点困难,因为在双引号字符串中没有干净的方法放置双引号;但是可以通过在双引号字符串周围放置单引号双引号来实现(哦,然后我总是在整个字符串周围放置双引号,尽管我不知道这是真的必要):

(如果您在解析时遇到问题,
是一个双引号(受单引号保护,以防止在
eval
获取它之前对其进行计算),
“$(…)”
是PlistBuddy的结果(受双引号保护),然后,
是另一个受保护的双引号

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

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

(这样做的目的是在转义任何嵌入的单引号后,在$MESSAGE周围加上单引号。)

这也转义所有其他元字符,从而防止eval在$CURRENT_YEAR中替换。
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}