With kernel 2.2, you can associate not only apps but also define
actions for file-types by writing your own scripts
Last month we learnt that with kernel 2.2 in Red Hat, Linuxprovides
"miscellaneous binary format support", that is, you can use
file-type associations to load associated apps. You can add support for
countless binary formats by just telling the kernel which interpreter to
run for which binary. For example, Java runtime for Java class files.
Though this can be done directly, sometimes you may need to write a
wrapper or a shell script, to tweak things a bit before actually calling
the interpreter. In this article, we’ll write a small wrapper to
associate a file type with its base app. We’ll then take this concept of
wrappers further to associate an action with a file-type.
Wrappers for binary format support
Sometimes, you may want to pass arguments to the interpreter, or the
interpreter may require a filename in a form different from the real
filename (like in Java classes, for x.class the interpreter needs to be
called with x, not x.class). In that case, you’ll have to write a small
wrapper, and specify this wrapper as the interpreter while registering.
Suppose you want to register HTML as a format, with Netscape as the
associated program. The trouble is, if you specify Netscape as the
interpreter, you’ll have a new Netscape process for every HTML file that
you open. With something as big as Netscape, running more than two
instances at the same time can make your system crawl. Fortunately,
Netscape can be invoked with an option to open a file in an already
running Netscape process. But we’ll have to write a small wrapper for
that:
#!/bin/sh
# where is netscape
NETSCAPE=/usr/bin/netscape
echo "Opening that in Netscape..."
FILE=$1
$NETSCAPE-remote "openURL (file:$FILE)"
if < $? -ne 0 >; then
echo "Netscape is not already running. Starting it..."
$NETSCAPE $FILE
fi
Save that in, say, /usr/bin/netscape_ wrapper and make it executable.
What it does is that it first tries to see if Netscape is already running.
If it is, it opens the file in Netscape, otherwise starts a new Netscape
process. Now we can register HTML with the wrapper as the interpreter:
% cd /proc/sys/fs/binfmt_misc
% echo ":html:E::html::/usr/bin/netscape_wrapper:" > register
And you’re done!
You can enable or disable particular binary formats, or the entire
feature. To disable format foo, echo 0 to /proc/sys/fs/binfmt_misc/foo,
and to enable it again echo 1 to it.
To remove an entry, echo -1 to it. To remove all entries, echo -1 to
/proc/sys/fs/binfmt_misc/status.
Making it rip
To register all these file types every time at bootup, you’ll have to
put all these commands in the file /etc/rc.d/rc.local (this may be
different on non-Red Hat systems). This file runs at every bootup after
all other init scripts.
For experts and adventurous
It should be apparent by now, that this ability to associate programs
with files can be used for much more than just recognizing various binary
formats. It can be used to associate an action with every file type. And
that is a very powerful idea.
For example, what is it that you usually want to do with a LaTeX file?
Run latex on it to get a DVI file, and then view that in xdvi. What if we
write a wrapper to do these two steps and register LaTeX files to use this
wrapper? Two cumbersome steps are replaced by one short invocation, the
filename itself. It doesn’t get any simpler. At the same time, this
doesn’t tie the user in with those two steps. The file can always be
used normally, just like any non-recognized file.