xmllint,bash和混合单和双qoutes

时间:2015-08-18 21:02:26

标签: bash xpath xmllint

我有一个非常类似的bash脚本:

# xpath query text
XPATH_FORM_ID="//form[@method='post']//input[@name='form_build_id']/@id" 
# surround with double quotes
XPATH_FORM_ID='"'"${XPATH_FORM_ID}"'"' 
DUMMY="$(xmllint --recover --html index.html --xpath ${XPATH_FORM_ID} 2> /dev/null)"
echo "Dummy: ${DUMMY}"
echo "xmllint --recover --html index.html --xpath ${XPATH_FORM_ID} 2> /dev/null"

它会回应这个:

Dummy: //form[@method='post']//input[@name='form_build_id']/@id
xmllint --recover --html index.html --xpath "//form[@method='post']//input[@name='form_build_id']/@id" 2> /dev/null

我期待回显的xmllint命令的输出:

$ xmllint --recover --html index.html --xpath "//form[@method='post']//input[@name='form_build_id']/@id" 2> /dev/null
 id="form-e9f5fe8e157329734722a31aed3f05fe" id="form-5de9fec879730335baa4860948245e27" id="form-83290b55eae399217486ec68e08be3d1" id="form-c1e275e97051aff023ca0526e17c37bb" id="form-13af4fe1b67e0b94462fa7d763b9bffe"

如何确保$()扩展能够恢复我的期望?

为什么我这样设置它的一些动机:

  • --recover --html因为大多数承诺xhtml的网站实际上都会产生符合要求的输出
  • 2> /dev/null放弃stderr以便--recover信息未在屏幕上结束
  • XPATH中的单引号,因为与字符串文字的属性比较似乎需要
  • 围绕XPATH的双引号,以允许更复杂的xpath表达式**

**将来,我想放大输入带有一个特定id的表单的name(html中充满了表单,这就是网站保留的方式他们分开)。当我有ID时,我想使用string()来获取id的文本部分。如果没有双引号,这将无法在命令行上运行,因此我认为在bash脚本中也需要它。

1 个答案:

答案 0 :(得分:1)

您无法区分数据中的语法引号(对shell有意义)和文字引号。添加文字双引号在改变shell处理相关字符串的方式方面绝对没有用:它们保留数据,永远不会成为语法而不调用eval,这是你非常不想要的要做。

以可重用的方式运行此查询的正确方法可能如下所示:

xpath_form_id="//form[@method='post']//input[@name='form_build_id']/@id"
query() {
  xmllint --recover --html index.html --xpath "$xpath_form_id" "$@" 2>/dev/null
}

此后:

content=$(query in.xml)

...或...

content=$(query <in.xml)

请注意,运行"$xpath_form_id"时的外部双引号是语义的,而不是文字的。它们不会传递给xmllint,而是被视为shell的指令,在扩展此变量时不会对xpath_form_id的内容进行字符串拆分或全局扩展。

相比之下,当你运行

xpath_form_id_q='"'"$xpath_form_id"'"'

...你在字符串上放了 literal 引号;它们不被shell视为如何在扩展时解析字符串的指令,而是传递给被调用的底层工具。