Thomas Lochmatter · Scatter · Secret Sharing · GPS bearing · LaTeX to SVG · Unicode

Lauching a C program like a script

Ever wanted to execute a *.c file directly? Try this:

#! /bin/sh
EXE=`basename -s .c "$0"`
tail -n +5 "$0" | cc -x c -o $EXE - && exec ./$EXE "$@"
exit

#include <stdio.h>

int main(int argc, char* argv[]) {
    printf("Program name: %s\n", argv[0]);

    printf("Arguments:\n");
    int i;
    for (i = 1; i < argc; i++) {
        printf("  %d: %s\n", i, argv[i]);
    }

    return 0;
}

Save the above as example.c and execute it like any other script:

chmod +x example.c
./example.c arg1 arg2

Just as with any other scripting language, the code is first compiled and then executed. This example program (or script, if you prefer) will simply print all the arguments.

How it works

Upon execution of the file example.c, a shell (/bin/sh) starts executing lines 2, 3 and 4 of the file. On these lines, the compiler (cc) is invoked to compile the file starting from line 5 (tail -n +5). If this succeeds, the program is started (exec) – otherwise, the shell script simply exits.

That's what many other scripting languages do as well, except that they do it automatically. Here, the compilation is triggered by a little shell script. The main differences with respect to a good scripting language are:

  • It only compiles the current file, and not the whole project.
  • It does not link any libraries. To do that, the necessary parameters (-l, -L, -I) would have to be passed manually to the cc command.
  • It recompiles the file each time it is launched. Some scripting languages do this as well, while others keep a cache of compiled files. The executable is left there, though.

The shell script could of course be enhanced to include all these features, but at some point it's probably easier to write a short Makefile. The above way should rather be thought of as simple way to execute a small C program.