将C或C++文件作为脚本运行

Rei*_*ica 26 c c++ shell

所以这可能是一个很长的镜头,但有没有办法将C或C++文件作为脚本运行?我试过了:

#!/usr/bin/gcc main.c -o main; ./main

int main(){ return 0; }
Run Code Online (Sandbox Code Playgroud)

但它说:

./main.c:1:2: error: invalid preprocessing directive #!
Run Code Online (Sandbox Code Playgroud)

Rem*_*o.D 29

对于C,您可以查看tcc,即Tiny C编译器.将C代码作为脚本运行是其可能的用途之一.

  • 哦,我喜欢这个.您所要做的就是添加`#!/ usr/bin/tcc -run` (3认同)

Ped*_*rda 23

简短回答:

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

诀窍是你的文本文件必须是有效的C/C++代码和shell脚本.请记住exit在解释器到达C/C++代码之前从shell脚本中调用exec魔法.

运行chmod +x main.c; ./main.c.

#!/usr/bin/tcc -run不需要类似shebang ,因为类Unix系统已经在shell中执行了文本文件.

(改编自此评论)


我在我的C++脚本中使用它:

//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;
}
Run Code Online (Sandbox Code Playgroud)

如果您的编译行增长太多,您可以使用预处理器(根据此答案改编),因为这个普通的旧C代码显示:

#if 0
    clang "$0" && ./a.out
    rm -f ./a.out
    exit
#endif
int main() {
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当然你可以缓存可执行文件:

#if 0
    EXEC=${0%.*}
    test -x "$EXEC" || clang "$0" -o "$EXEC"
    exec "$EXEC"
#endif
int main() {
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在,对于真正古怪的Java开发人员:

/*/../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;
    }
}
Run Code Online (Sandbox Code Playgroud)

D程序员只需将一个shebang放在文本文件的开头,而不会破坏语法:

#!/usr/bin/rdmd
void main(){}
Run Code Online (Sandbox Code Playgroud)

  • 要将参数传递给可执行的c ++代码,请在./a.out之后添加“ $ @”;因此它将是-------------------------- ------ // usr / bin / clang ++ -O3 -std = c ++ 11“ $ 0” &amp;&amp; ./a.out“ $ @”; 出口 (2认同)

Joh*_*ica 17

$ 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!
Run Code Online (Sandbox Code Playgroud)

sed命令获取.c文件并剥离hash-bang行.2,$p表示将第2行打印到文件末尾; "$@"扩展到runc脚本的命令行参数,即"main.c".

sed的输出通过管道输送到gcc.传递-给gcc告诉它从stdin读取,当你这样做时,你还必须指定源语言,-x因为它没有文件名可供猜测.


小智 10

由于shebang行将传递给编译器,而#表示预处理器指令,它将阻塞#!.

你可以做的是将makefile嵌入.c文件中(如本xkcd线程中所述)

#if 0
make $@ -f - <<EOF
all: foo
foo.o:
   cc -c -o foo.o -DFOO_C $0
bar.o:
   cc -c -o bar.o -DBAR_C $0
foo: foo.o bar.o
   cc -o foo foo.o bar.o
EOF
exit;
#endif

#ifdef FOO_C

#include <stdlib.h>
extern void bar();
int main(int argc, char* argv[]) {
    bar();
    return EXIT_SUCCESS;
}

#endif

#ifdef BAR_C
void bar() {
   puts("bar!");
}
#endif
Run Code Online (Sandbox Code Playgroud)

#if 0 #endif围绕makefile 的对确保预处理器忽略该部分文本,并且EOF标记标记make命令应停止解析输入的位置.


Eli*_*sky 7

CINT:

CINT是C和C++代码的解释器.例如,对于快速开发比执行时间更重要的情况,它很有用.使用解释器可以大大减少编译和链接周期,从而促进快速开发.即使对于兼职程序员来说,CINT使C/C++编程也很有趣.


rya*_*obs 5

您可能想为此考虑结帐ryanmjacobs / c。它充当您最喜欢的编译器的包装。

#!/usr/bin/c
#include <stdio.h>

int main(void) {
    printf("Hello World!\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用的好处c是,您可以选择要使用的编译器,例如

$ export CC=clang
$ export CC=gcc
Run Code Online (Sandbox Code Playgroud)

因此,您也可以获得所有喜欢的优化!击败那个tcc -run

您还可以将编译器标志添加到shebang,只要它们以--字符结尾:

#!/usr/bin/c -Wall -g -lncurses --
#include <ncurses.h>

int main(void) {
    initscr();
    /* ... */
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c也使用$CFLAGS$CPPFLAGS如果它们也被设置。


Tam*_*ola 5

#!/usr/bin/env sh
tail -n +$(( $LINENO + 1 )) "$0" | cc -xc - && { ./a.out "$@"; e="$?"; rm ./a.out; exit "$e"; }

#include <stdio.h>

int main(int argc, char const* argv[]) {
    printf("Hello world!\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这样也可以正确转发参数和退出代码。


归档时间:

查看次数:

11199 次

最近记录:

5 年,10 月 前