为什么我不能在bash中用引号生成换行符?

时间:2016-03-24 23:38:59

标签: bash newline quote

无论我做什么,我都无法在引号中使用引号来保留输出。我是什么做的?这是OS X中的bash。我的代码在这里:Gist

read -d '' sbt_text=$(cat <<"EOF"
#!/bin/bash
SBT_OPTS="-Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M";
java $SBT_OPTS -jar `dirname $0`/sbt-launch.jar "$@"
EOF
)

echo $sbt_text

#!/bin/bash > SBT_OPTS="-Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M"; > java -jar /sbt-launch.jar ""

2 个答案:

答案 0 :(得分:6)

你可能想要的是:

IFS= read -d '' -r sbt_text <<"EOF"
#!/bin/bash
SBT_OPTS="-Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M";
java $SBT_OPTS -jar `dirname $0`/sbt-launch.jar "$@"
EOF

echo "$sbt_text"

虽然您的read命令无法发布,但 不是双引号 $sbt_text将始终执行word splitting (还有pathname expansion (globbing)),传递给echo时,表示任何内部空白都标准化为单个空格

为了在类似POSIX的shell中保留变量 as 的值 - 而不使其受到上述shell expansions的约束 - 你必须双引用

关于read命令,请注意:

  • -r可以防止输入中\个实例的意外解释。
  • 预先IFS=确保here-document中的每一行都按原样保留(不修剪前导和尾随空格)
  • 由于$(...)(a command substitution)直接提供stdin输入,因此不需要here-documentcat<<,这是read从中输入的地方。
    • 通过在sbt_text=$(...)命令中使用read,您基本上将命令替换($(...)的输出作为(最终无效的)变量名称的一部分而不是提供输入,导致read仍然等待stdin输入。
    • 使用 分配sbt_text=$(cat <<"EOF" ...)(没有read)几乎可以满足您的需求(尽管以外部实用程序cat调用为代价),除了命令替换会剥离任何尾随换行符。

答案 1 :(得分:2)

您应引用变量

echo "$sbt_text"

这可以防止Bash在替换您的变量后执行分词(和 globbing ,即扩展通配符,如*?)参数扩展)。请注意,为IFS设置read不会阻止echo命令行上的字拆分。试试这个很有趣:

( IFS= ; echo $sbt_text )

VS

IFS= echo $sbt_text ### won't work

第二个例子不起作用 - 子shell(( ))在这里是必要的,因为IFS被调用shell解释为分词而不是readIFS中解释问题的代码示例。

当然这也有效(但&#34;废墟&#34;你的IFS= ; echo $sbt_text ):

my_modules