shell heredoc 微妙之处
here doc 的一般用法是:
[cmd] <<word
here-document
delimiter
here-document
delimiter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#!/bin/sh # write heredoc text to file cat > file <<EOF some text write to file EOF # show file cat file # save heredoc text to var var=`cat << EOF some text save to var EOF ` # show var echo $var |
使用 捕获 heredoc 内容比较丑陋,但这是我目前能找到的不需要中间文件就可以将heredoc内容存到变量中的唯一方式($(..)也可以,但似乎更丑陋,并且移植性更差)。我觉得比较好的捕获heredoc内容的方式应该象这样,不需要在delimiter 之后再放一个标记:
1 2 3 |
capture var <<"EOF" some text EOF |
然而有两点需要注意:
当word中含有双引号(” )时,heredoc 结束标记(delimiter )需要写成 按shell 移除引号的规则 移除引号之后 的形式。比如:
1 2 |
word="EOF" delimiter=EOF |
在这种情况下(word中包含引号),heredoc的文本内容会原原本本地输出,而不会被shell扩展。 反之 (word中无引号) , heredoc的内容会按shell扩展规则被扩展,例如将$1扩展成参数等等,并且 newline 会被删除。
还有一种情况,就是重定向 符号 << 可以使用 <
可以使用 heredoc 直接在 shell 中写比较复杂的 awk 程序,比直接在在引号中写要可读、易懂得多:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#!/bin/sh if [ $# -lt 1 ]; then echo usage: $0 files exit 1 fi prog=`cat <<"EOF" { count[$1] += $2; } END{ for (k in count) { printf "%s\t%d\n", k, count[k]; } } EOF ` awk "$prog" "$@" |