我想使用 bash here doc 语法来构建一个长字符串。我希望 heredoc 忽略换行符/空格/制表符,即使我为了代码清晰而使用换行符也是如此。
我认为这会起作用:
#!/bin/bash
#http://unix.stackexchange.com/questions/20035/how-to-add-newlines-into-variables-in-bash-script
IFS= read -r -d '' NS_LOG<<-EOF
*=error|warn|prefix_node|prefix_func
:PointToPointNetDevice
:ClockTest
:ClockPerfect
:TcpTestSuite
:TcpRxBuffer
:TcpTxBuffer
:TcpHeader=*
:TcpL4Protocol
:TraceHelper:PointToPointHelper
EOF
echo $NS_LOG
export NS_LOG
但是 bash 在某处追加了行与行之间的空格,而不是拥有所需的
*=error|warn|prefix_node|prefix_func:PointToPointNetDevice:ClockTest:ClockPerfect:Clock
我在运行 $ ./launch_myscript.sh 时有:
*=error|warn|prefix_node|prefix_func :PointToPointNetDevice :ClockTest :ClockPerfect :Clock etc...
我的 bash --version:
GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)
刚在推荐帖里看到这个Bash: Why is echo adding extra space? .如何防止 NS_LOG 被视为多个参数?最终目标是导出该变量。
最佳答案
你的 read
命令非常明确地将换行符视为数据:通过清除 IFS 并传递 -d ''
,你告诉read
不要将空白字符视为特殊字符;因为它们并不特殊,所以它们像其他所有内容一样进入输出变量。但是,您可以稍后将它们取出:
IFS= read -r -d '' NS_LOG <<'EOF'
...content...
EOF
NS_LOG=${NS_LOG//[[:space:]]/} ## replace all whitespace with the empty string
printf '%s\n' "$NS_LOG" ## the quotes are important!
在 http://ideone.com/fWhzBB 查看此代码段的运行及其输出.
注意事项:
-
<<'EOF'
防止在 heredoc 本身内发生扩展;与<<EOF
,$foo
,$(foo)
等会很特别。 -
<<-
仅修剪前导制表符,不修剪任何其他形式的空格;没有它通常更安全。 -
echo $foo
字符串拆分和全局扩展$foo
的内容,将此过程创建的每个单词作为单独的参数传递;echo
然后在每个参数之间放置空格。echo "$foo"
确保整个扩展被视为单个单词。参见 BashPitfalls #14 . - 使用
echo
建议不要使用重要或未知数据 in the relevant portion of the POSIX specification ;printf
是首选替代品。当内容包含反斜杠文字时,POSIX echo 被明确允许以未定义的方式运行,并且命令的 BSD 和 AT&T 派生形式明确不兼容,彼此之间以及与通用 GNU 实现(提供-e
标志, POSIX 规范要求在其输出中简单地打印-e
。
关于bash 这里的文档语法我想忽略换行符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31931696/