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:
$ 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.