Run C/C++ scripts, just like you would do with Python, Ruby etc.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.


Run C/C++ scripts, just like you would do with Python, Ruby etc.

Build Status


  1. My C script, test.c:

    #!/usr/bin/env crun
    /* -Wall -O3 */
    #include <stdio.h>
    int main(int argc, char *argv[]) {
        printf("Hello, world %s!", argv[1]);
        return 0;

    Note: We added a shebang on the 1st line! (#!/usr/bin/env crun)
    Note: We added flags to be used in compilation in 2nd line! (-Wall -O3)

  2. Make it executable

    $ chmod +x test.c
  3. Run it

    $ ./test.c Koninchwa

    Note: We can pass arguments to the script! (Koninchwa)


I just love C! (and why not?!) Okay! This allows me to write more C code for day-to-day tasks, not just when you want to speed up some component of an application. It makes C more practical for use. Also, it is really handy when you are learning C/C++; everything important is contained in the single file.

The first time you invoke a crun script, it is compiled using cc (for C files with extension .c) or g++ (for CPP files with extensions other than .c) in the directory holding the script, stored away in /tmp/crun and run immediately. Subsequent invocations will run the compiled executable, rather than re-compile, unless the source file has been modified (in which case we compile!).

If you may want to change the directory where the executables are stored, you can use the ${CRUN_CACHE_DIR} variable. This is useful if you wish to cache executables across restarts. If no directory exists at ${CRUN_CACHE_DIR} yet, it will be created using mkdir -p. Make sure crun has permissions to write to the directory.

If you have compilation flags that you need to be passed to cc/g++, you place them in the 2nd line separately, inside a comment using /* and */. For example,

/* -Wall -O3 */

Note: While you can start your code in the 2nd line, it is advisable you avoid doing so since crun, in the case the 2nd line contains /* and */, will assume it's being fed compilation flags. This may lead to some weird compilation errors!


By default, bash expressions in the string holding the flags are not are evaluated. This is a neat feature but I do understand it adds a new edge in the attack graph. You will need to explicitly enable this feature, using the environment variable ${CRUN_DO_EVAL} or the command-line argument --do-eval. If enabled, a string such as /* $(pkg-config --libs libuv) */ for the compilation flags will be evaluated. So,

$ export CRUN_DO_EVAL=1  # you could place this in your ~/.bashrc (or equivalent)

# OR

$ crun --do-eval filename.c

Note: Do not run scripts you do not trust, even if eval is disabled! Always remember, no system/application can ever be 100% secure!

To allow maximum efficiency, you can create a quick template of a script using:

$ crun --create my_script

This will create an executable crun script that you can edit to add the meat.

In some cases, you want the script re-compiled, maybe you've modified some library files. To bypass the cache:

$ crun --force-compile my_script

Sometimes, you may want to debug your script with gdb, or you just want to skip running the compiled executable:

$ crun --just-compile my_script

Since --just-compile will make crun not run your executable, any arguments passed will be considered to be more compilation flags to use. It also echo's back the path to the compiled executable. So you could do something like:

$ gdb `crun --just-compile script.c -Wall -g`
$ valgrind --leak-check=yes `crun --just-compile script.c -Wall -g` arg1 arg2


It's simple!

  1. Download
  2. Rename it to crun
  3. Place it in a directory in your $PATH.

For example,

$ cd ~/bin/
$ wget
$ mv crun


The master branch always remains stable. Development is done on the develop branch.


The MIT License (MIT)

Copyright (c) 2015-2016 GochoMugo