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
#endif
int main() {
    return 0;
}

Of course you can cache the executable:

#if 0
    EXEC=${0%.*}
    test -x "$EXEC" || clang "$0" -o "$EXEC"
    exec "$EXEC"
#endif
int 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/rdmd
void main(){}

See:

Leave a Comment