我有一个非常类似的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
信息未在屏幕上结束 **将来,我想放大输入带有一个特定id
的表单的name
(html中充满了表单,这就是网站保留的方式他们分开)。当我有ID时,我想使用string()
来获取id
的文本部分。如果没有双引号,这将无法在命令行上运行,因此我认为在bash脚本中也需要它。
答案 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视为如何在扩展时解析字符串的指令,而是传递给被调用的底层工具。