我正在使用进程替换来创建我编写的速记内联XSL函数......
function _quickxsl() {
if [[ $1 == "head" ]] ; then
cat <<'HEAD'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY apos "'">
]>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:func="http://exslt.org/functions"
xmlns:kcc="http://www.adp.com/kcc"
extension-element-prefixes="func kcc">
HEAD
else
cat <<'FOOT'
</xsl:stylesheet>
FOOT
fi
}
function quickxsl() {
{
_quickxsl head && cat && _quickxsl foot
} | xsltproc - "$@"
}
如果我提供真实文件作为xsltproc的参数,它似乎工作正常。在另一方面,我用进程替换调用它:
$ quickxsl <(cat xml/kconf.xml) <<QUICKXSL
QUICKXSL
warning: failed to load external entity "/dev/fd/63"
unable to parse /dev/fd/63
现在,我知道管道路径正被提供给通过另一个管道(xsltproc)连接的子进程。所以我稍微重写了一遍:
function quickxsl() {
xsltproc - "$@" < <( _quickxsl head && cat && _quickxsl foot )
}
似乎解决了一些问题
/dev/fd/63:1: parser error : Document is empty
^
/dev/fd/63:1: parser error : Start tag expected, '<' not found
^
unable to parse /dev/fd/63
知道管道为什么不能继承?
更新
如果我再次简化quickxsl功能:
function quickxsl() {
xsltproc <( _quickxsl head && cat && _quickxsl foot ) "$@"
}
我遇到同样的问题,但很容易识别哪个fifo导致问题有点xtrace ...
$ quickxsl <(cat xml/kconf.xml) <<QUICKXSL
QUICKXSL
+ quickxsl /dev/fd/63
++ cat xml/kconf.xml
+ xsltproc /dev/fd/62 /dev/fd/63
++ _quickxsl head
++ [[ head == \h\e\a\d ]]
++ cat
++ cat -
++ _quickxsl foot
++ [[ foot == \h\e\a\d ]]
++ cat
/dev/fd/62:1: parser error : Document is empty
^
/dev/fd/62:1: parser error : Start tag expected, '<' not found
^
cannot parse /dev/fd/62
本练习的目的是让“过程替代”#39; pipe,连接到一个函数,该函数返回XML上的标准输出,它可以正常工作。如果我将内容写入文件并将其传递给函数,一切都很好。如果我使用流程替换,则子流程无法从管道读取,并且管道显示为关闭或无法访问。例如:
quickxsl <(my_soap_service "query") <<XSL
<xsl:template match="/">
<xsl:value-of select="/some/path/text()"/>
</xsl:template>
XSL
如您所见,它提供了一些快捷方式。
更新
一个好处是管道不能连续打开或关闭。 xsltproc的Strace输出显示它只打开文件一次。
$ grep /dev/fd !$
grep /dev/fd /tmp/xsltproc.strace
execve("/usr/bin/xsltproc", ["xsltproc", "/dev/fd/62"], [/* 31 vars */]) = 0
stat("/dev/fd/62", {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
stat("/dev/fd/62", {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
stat("/dev/fd/62", {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
open("/dev/fd/62", O_RDONLY) = 3
write(2, "/dev/fd/62:1: ", 14) = 14
write(2, "/dev/fd/62:1: ", 14) = 14
write(2, "cannot parse /dev/fd/62\n", 24) = 24
Blimey,我忽略了寻求:
read(3, "<?xml version=\"1.0\" encoding=\"UT"..., 16384) = 390
read(3, "", 12288) = 0
lseek(3, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
lseek(3, 18446744073709547520, SEEK_SET) = -1 ESPIPE (Illegal seek)
read(3, "", 4096) = 0
答案 0 :(得分:0)
似乎我在xsltproc中发现了一个错误。它不识别FIFO文件类型,并在读取文档后尝试寻找FIFO文件描述符。我提出了一个错误。解决方法是解析FIFO文件类型的xsltproc参数,并将它们转换为可由xsltproc搜索的临时文件。