So this is probably a long shot, but is there any way to run a C or C++ file as a script? I tried:
#!/usr/bin/gcc main.c -o main; ./main
int main(){ return 0; }
But it says:
./main.c:1:2: error: invalid preprocessing directive #!
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:
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/bash
sed -n '2,$p' "$@" | gcc -o /tmp/a.out -x c++ - && /tmp/a.out
rm -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.c
hello 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With