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

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

问题描述:

我无法在 bash 脚本中保留空格:

I'm having trouble preserving whitespace in a bash script:

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 的相关部分:

The relevant section Info.plist:

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

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

The script reads a value from a plist, then substitutes another variable (CURRENT_YEAR) into the the value that was read from the plist.

问题是 MESSAGE 中的新行导致了问题.如果我使用 \n 则显示 'n' 而不是新行.如果使用了实际的换行符,则该命令将失败,因为 'All' 被解释为一个新命令.

The problem is that the new line in MESSAGE is causing problems. If I use \n then an 'n' is displayed instead of a new line. If an actual new line character is used then the command fails because 'All' is interpreted as a new command.

如何转义新行?有一个更好的方法吗?我的 bash-foo 很少.

How do I escape the new line? Is there a better way to do this? I have very little bash-foo.

感谢您的帮助.解决方案是疯狂使用引号.最终结果如下:

Thanks for the help. The solution was to go crazy with quotes. Here's the finished result:

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}

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

You have to get double-quotes around the string being eval'ed (so it'll substitute for the ${} expression, but not treat the newline as a separator between commands). This is kind of difficult, since there's no clean way to put a double-quote inside a double-quoted string; but you can do it by putting single-quoted double-quotes around the double-quoted string (oh, and then I always put double-quotes around the whole thing, even though I don't know that it's truly necessary):

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

(如果您在解析时遇到问题,'"' 是一个双引号(受单引号保护以防止它被评估,直到 evalit),"$(...)" 是 PlistBuddy 的结果(受双引号保护),然后 '"' 是另一个受保护的双引号.

(If you're having trouble parsing that, '"' is a double-quote (protected by single-quotes to keep it from being evaluated until eval gets it), "$(...)" is the result of PlistBuddy (protected by double-quotes), and then '"' is another protected double-quote.

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

After that I think your PlistBuddy Set command will work ok, but I've had to quote its values before, so just in case:

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

(在转义任何嵌入的单引号之后,在 $MESSAGE 周围放置单引号.)

(what that does is put single-quotes around $MESSAGE, after escaping any embedded single-quotes.)