Run C or C++ file as a script Run C or C++ file as a script shell shell

Run C or C++ file as a script


Short answer:

//usr/bin/clang "$0" && exec ./a.out "$@"int main(){    return 0;}

The trick is that your text file must be both valid C/C++ code and shell script. Remember to exit from the shell script before the interpreter reaches the C/C++ code, or invoke exec magic.

Run with chmod +x main.c; ./main.c.

A shebang like #!/usr/bin/tcc -run isn't needed because unix-like systems will already execute the text file within the shell.

(adapted from this comment)


I used it in my C++ script:

//usr/bin/clang++ -O3 -std=c++11 "$0" && ./a.out; exit#include <iostream>int main() {    for (auto i: {1, 2, 3})        std::cout << i << std::endl;    return 0;}

If your compilation line grows too much you can use the preprocessor (adapted from this answer) as this plain old C code shows:

#if 0    clang "$0" && ./a.out    rm -f ./a.out    exit#endifint main() {    return 0;}

Of course you can cache the executable:

#if 0    EXEC=${0%.*}    test -x "$EXEC" || clang "$0" -o "$EXEC"    exec "$EXEC"#endifint main() {    return 0;}

Now, for the truly eccentric Java developer:

/*/../bin/true    CLASS_NAME=$(basename "${0%.*}")    CLASS_PATH="$(dirname "$0")"    javac "$0" && java -cp "${CLASS_PATH}" ${CLASS_NAME}    rm -f "${CLASS_PATH}/${CLASS_NAME}.class"    exit*/class Main {    public static void main(String[] args) {        return;    }}

D programmers simply put a shebang at the beginning of text file without breaking the syntax:

#!/usr/bin/rdmdvoid main(){}

See:


For C, you may have a look at tcc, the Tiny C Compiler. Running C code as a script is one of its possible uses.


$ cat /usr/local/bin/runc#!/bin/bashsed -n '2,$p' "$@" | gcc -o /tmp/a.out -x c++ - && /tmp/a.outrm -f /tmp/a.out$ cat main.c#!/bin/bash /usr/local/bin/runc#include <stdio.h>int main() {    printf("hello world!\n");    return 0;}$ ./main.chello world!

The sed command takes the .c file and strips off the hash-bang line. 2,$p means print lines 2 to end of file; "$@" expands to the command-line arguments to the runc script, i.e. "main.c".

sed's output is piped to gcc. Passing - to gcc tells it to read from stdin, and when you do that you also have to specify the source language with -x since it has no file name to guess from.