Implement standard shell script header?

We all know that the standard UNIX shell script can start with something like this:
#!/usr/bin/env python

Now, if you just add this line to “hsimple.C” and make the script executable:
#!/usr/bin/env root
it will failed like this:

$ ./hsimple.C 
  *******************************************
  *                                         *
  *        W E L C O M E  to  R O O T       *
  *                                         *
  *   Version   5.34/00       5 June 2012   *
  *                                         *
  *  You are welcome to visit our Web site  *
  *          http://root.cern.ch            *
  *                                         *
  *******************************************

ROOT 5.34/00 (branches/v5-34-00-patches@44555, Mar 14 2013, 11:26:00 on linuxx8664gcc)

CINT/ROOT C/C++ Interpreter version 5.18.00, July 2, 2010
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0] 
Processing ./hsimple.C...
Error: Function hsimple() is not defined in current scope  :0:
*** Interpreter error recovered ***
root [1]

So, why not modify the main executable “root.exe”, so that it can handle the standard shell script header? It will be more convinient to data analyzers.

Hi Exaos,

I have been tinkering with for some time as well, but I believe there are just too many issues with what you propose. The major issue is that !#/bin/env root would be a valid shebang line, but it also is a somewhat valid C preprocessor directive, and allowing this would make CINT macros even less valid as compiled code.

Of course none of this is an issue if you just use PyROOT where #!/bin/env python is perfectly fine.

If you have root access on the Linux machine were you want to do this you can use the kernel binfmt support which can hardwire an interpreter to certain filetypes, e.g. to have ROOT invoked for executable *.C files you could

$ echo ':ROOT:E::C::/usr/bin/root:' > /proc/sys/fs/binfmt_misc/register

which would allow exactly what you want without having to modify the macros. To pass certain flags to ROOT (e.g. -q) register a wrapper script instead of the ROOT executable. Of course this doesn’t work “out of the box” and could make scripts unportable.

Sorry for necrobumping, but I did some research and putting the following:

//usr/bin/env root -l $0; exit $?

at the top of my ROOT macros works for me. I’m not 100% sure about portability though, I just tested it on my Linux machine. Could you check?

1 Like

Brilliant. You’ve turned the ROOT macro into a shell script that runs itself, and the doubled slash at the beginning turns that line into a C++ comment (while not causing problems for the shell).

Here I posted a more complex example that handles also command line arguments, if anyone’s interested:

1 Like