Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run C or C++ file as a script

Tags:

c++

c

shell

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 #!
like image 494
Brendan Long Avatar asked Mar 20 '10 07:03

Brendan Long


3 Answers

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:

  • https://unix.stackexchange.com/a/373229/23567
  • https://stackoverflow.com/a/12296348/199332
like image 176
Pedro Lacerda Avatar answered Sep 18 '22 14:09

Pedro Lacerda


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.

like image 29
Remo.D Avatar answered Sep 19 '22 14:09

Remo.D


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

like image 45
John Kugelman Avatar answered Sep 19 '22 14:09

John Kugelman