3

I have (foolishly?) written a couple of moderately general-purpose xslt scripts.

I'd quite like to turn these into executables that read an xml document from standard in or similar.

The way you do this with other languages is to use a shbang.

Is there an easy / standard way to do this with xsltproc and friends? Sure I could hack up a wrapper around xsltproc that pulls off the first comment line... but if there is something approximating a standard this would be nicer to use.

Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
Att Righ
  • 1,176
  • 11
  • 29
  • 2
    Back in 2006: https://mail.gnome.org/archives/xslt/2006-January/msg00011.html – muru Nov 01 '17 at 04:18
  • 1
    **The only right solution is to have OS support for what you want to do.** :) There's something interesting about a programming language expecting the linux kernel to implement features so that their scripts can run... – Att Righ Nov 01 '17 at 19:24
  • 1
    that's essentially what binfmt is. – muru Nov 01 '17 at 22:57

2 Answers2

5

You could use the generic binfmt-misc kernel module that handles which interpreter is used when an executable file is run. It is typically used to allow you to run foreign architecture files without needing to prefix them with qemu or wine, but can be used to recognise any magic characters sequence in a file header, or even a given filename extension, like *.xslt. See the kernel documentation.

As an example, if you have a file demo.xslt that starts with the characters

<xsl:stylesheet version=...

you can ask the module to recognise the string <xsl:stylesheet at offset 0 in the file and run /usr/bin/xsltproc by doing as root

colon=$(printf '\\x%02x' \':) # \x3a
echo ":myxsltscript:M::<xsl${colon}stylesheet::/usr/bin/xsltproc:" >/etc/binfmt.d/myxslt.conf 
cat /etc/binfmt.d/myxslt.conf >/proc/sys/fs/binfmt_misc/register

You don't need to go via the /etc file unless you want the setting to be preserved over a reboot. If you don't have the /proc file, you will need to mount it first:

mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc

Now, if you chmod +x demo.xslt you can run demo.xslt with any args and it will run xsltproc with the filename demo.xslt provided as an extra first argument.

To undo the setup, use

echo -1 >/proc/sys/fs/binfmt_misc/myxsltscript
meuh
  • 49,672
  • 2
  • 52
  • 114
  • This approach is ingenious. It's a shame that this approach doesn't deal well with initial comments and whitespace. I guess you really want to do stuff based on the extension. – Att Righ Nov 01 '17 at 19:19
  • Ah you can select the interpreter based on extensions... https://www.kernel.org/doc/Documentation/admin-guide/binfmt-misc.rst . It's a bit magically and machine specific, but it does work. – Att Righ Nov 01 '17 at 19:22
2

There is no way to change an XSLT stylesheet into an executable using a shebang.

fpmurphy
  • 4,556
  • 3
  • 23
  • 26
  • Hmm... I have an ongoing concern about "that's impossible" answers. While you are probably technically correct that a shebang is not valid xml that doesn't necessarily mean that there is a standard way achieving the effect that I was after. I could simply write my xslt scripts in a non-standard definition of xslt that allows hash bangs on the first line and use an interpreter that strips them. – Att Righ Nov 01 '17 at 18:13
  • 1
    @AttRigh. You certainly can try. Please publish your work when you are done. I would point out that "a non-standard definition of xslt" is not XSLT by definition. – fpmurphy Nov 01 '17 at 18:23
  • "a non-stanard defintion is not" is not XSLT... well that's what non-standard means isn't it :P. But yeah. you end up with xslt files that can only be used as executables and can't be fed into other programmers, nevertheless this is the approach some other languages that don't support # comments use. Erlang being a good example. – Att Righ Nov 01 '17 at 19:05