在Bash中,here-document如何包含变量然后存储在变量中?

时间:2014-12-02 17:14:51

标签: bash variables heredoc

我在Bash脚本中有以下内容:

URL="${1}"
IFS= read -d '' code << "EOF"
import urllib2
from BeautifulSoup import BeautifulSoup
page = BeautifulSoup(urllib2.urlopen("${URL}"))
images = page.findAll('img')
for image in images:
    print(image["src"])
EOF
python <(echo "${code}")

如何更改here-document的定义方式(例如,不使用read),以便在here-document中解析变量${URL},然后将here-document存储在变量${code}?目前,here-document成功存储在变量中,但是here-document中的变量没有被解析。

2 个答案:

答案 0 :(得分:4)

EOF删除引号:

URL="${1}"
IFS= read -d '' code <<EOF
import urllib2
from BeautifulSoup import BeautifulSoup
page = BeautifulSoup(urllib2.urlopen("${URL}"))
images = page.findAll('img')
for image in images:
    print(image["src"])
EOF
python <(echo "${code}")

根据man bash

  

如果引用了单词中的任何字符,则分隔符是结果   引用删除单词,和here-document中的行不是   扩展

答案 1 :(得分:0)

我不打算覆盖或替换@anubhava给出的字面问题的(完全正确的)答案 - 答案是正确的,并且在中替换的文档不是< / em>源代码,它的用法完全合适。


将变量替换为代码(无论是在heredoc中还是其他方式)实际上是一种相当危险的做法 - 您可能会遇到Bobby Tables的表亲。

更好的方法是在带外发送变量,以防止任何解析为代码的可能性。在awk中,这是通过-vkey=val完成的;对于Python,一种简单的方法是使用环境:

export URL="${1}"
IFS= read -d '' code << "EOF"
import urllib2, os
from BeautifulSoup import BeautifulSoup
page = BeautifulSoup(urllib2.urlopen(os.environ['URL']))
images = page.findAll('img')
for image in images:
    print(image["src"])
EOF
python <(echo "${code}")

原始代码的更改:

  • 在分配export
  • 时使用URL
  • Python中的import os
  • Python中对os.environ['URL']的引用。

至于为什么这种方法更可取 - 考虑如果您正在处理包含字符串"+__import__('shutil').rmtree('/')+"的URL,会发生什么。运行

page = BeautifulSoup(urllib2.urlopen(""+__import__('shutil').rmtree('/')+""))

......可能不会产生你想要的效果。