Skip to content

Instantly share code, notes, and snippets.

@jdarpinian
Last active September 28, 2025 09:40
Show Gist options
  • Select an option

  • Save jdarpinian/1952a58b823222627cc1a8b83a7aa4e2 to your computer and use it in GitHub Desktop.

Select an option

Save jdarpinian/1952a58b823222627cc1a8b83a7aa4e2 to your computer and use it in GitHub Desktop.
Add one line to your C/C++ source to make it executable.
///$(which true);FLAGS="-g -Wall -Wextra --std=c17 -O1 -fsanitize=address,undefined";THIS_FILE="$(cd "$(dirname "$0")"; pwd -P)/$(basename "$0")";OUT_FILE="/tmp/build-cache/$THIS_FILE";mkdir -p "$(dirname "$OUT_FILE")";test "$THIS_FILE" -ot "$OUT_FILE" || $(which clang || which gcc) $FLAGS "$THIS_FILE" -o "$OUT_FILE" || exit $?;exec bash -c "exec -a \"$0\" \"$OUT_FILE\" $([ $# -eq 0 ] || printf ' "%s"' "$@")"
#include <stdio.h>
int main() {
printf("Hello world!\n");
return 0;
}
///$(which true);FLAGS="-g -Wall -Wextra --std=c++23 -O1 -fsanitize=address,undefined";THIS_FILE="$(cd "$(dirname "$0")"; pwd -P)/$(basename "$0")";OUT_FILE="/tmp/build-cache/$THIS_FILE";mkdir -p "$(dirname "$OUT_FILE")";test "$THIS_FILE" -ot "$OUT_FILE" || $(which clang++ || which g++) $FLAGS "$THIS_FILE" -o "$OUT_FILE" || exit $?;exec bash -c "exec -a \"$0\" \"$OUT_FILE\" $([ $# -eq 0 ] || printf ' "%s"' "$@")"
#include <iostream>
int main() {
std::cerr << "Hello, world!" << std::endl;
return 0;
}
#!/bin/bash
///$(which true);FLAGS="-g -Wall -Wextra --std=c17 -O1 -fsanitize=address,undefined";THIS_FILE="$(cd "$(dirname "$0")"; pwd -P)/$(basename "$0")";OUT_FILE="/tmp/build-cache/$THIS_FILE";mkdir -p "$(dirname "$OUT_FILE")";test "$THIS_FILE" -ot "$OUT_FILE" || tail -c +12 "$0" | $(which clang || which gcc) $FLAGS -xc - -o "$OUT_FILE" || exit $?;exec -a "$0" "$OUT_FILE" "$@"
#include <stdio.h>
int main() {
printf("Hello world!\n");
return 0;
}
#!/bin/bash
///$(which true);FLAGS="-g -Wall -Wextra --std=c++23 -O1 -fsanitize=address,undefined";THIS_FILE="$(cd "$(dirname "$0")"; pwd -P)/$(basename "$0")";OUT_FILE="/tmp/build-cache/$THIS_FILE";mkdir -p "$(dirname "$OUT_FILE")";test "$THIS_FILE" -ot "$OUT_FILE" || tail -c +12 "$0" | $(which clang++ || which g++ || which cpp) $FLAGS -xc++ - -o "$OUT_FILE" || exit $?;exec -a "$0" "$OUT_FILE" "$@"
#include <iostream>
int main() {
std::cerr << "Hello, world!" << std::endl;
return 0;
}
@duaneking

Copy link
Copy Markdown

This is so dirty I would never tolerate it in a source tree of mine, but its still a nice hack.

@yath

yath commented Feb 6, 2018

Copy link
Copy Markdown

I would be surprised if any of these that don’t have #!/bin/bash there would run without a shell but, say, under /usr/bin/env. Most likely the shell is attempting an execve() call and then falls back to parsing the file as a shell script.

Edit: I just realized that this behaviour of running a file as a shell script if it’s not otherwise executable is a special behaviour of execlp() and execvp() - not the shell. From POSIX.1-2008:

There are two distinct ways in which the contents of the process image file may cause the execution to fail, distinguished by the setting of errno to either [ENOEXEC] or [EINVAL] (see the ERRORS section). In the cases where the other members of the exec family of functions would fail and set errno to [ENOEXEC], the execlp() and execvp() functions shall execute a command interpreter and the environment of the executed command shall be as if the process invoked the sh utility using execl() as follows:

execl(<shell path>, arg0, file, arg1, ..., (char *)0);

where is an unspecified pathname for the sh utility, file is the process image file, and for execvp(), where arg0, arg1, and so on correspond to the values passed to execvp() in argv[0], argv[1], and so on.

Still, you probably don’t want to rely on your caller calling the right exec*() variant for the shebang-less files to work (which, incidentally, both env and perl do). :)

I learned something. Thanks.

@yath

yath commented Feb 6, 2018

Copy link
Copy Markdown

And to add something constructive to this thread: #!/usr/bin/tcc -run

@sol-vin

sol-vin commented Feb 7, 2018

Copy link
Copy Markdown

Thank you for this <3

@Jartza

Jartza commented Feb 7, 2018

Copy link
Copy Markdown

These won't work on Mac because true is not in /bin, but replace it with ///$(which true) and they do.

@bontchev

bontchev commented Feb 7, 2018

Copy link
Copy Markdown

gcc does not like the option -fsanitize=address,undefined on my machine; I had to delete that part, in order to make it work.

@kevien

kevien commented Feb 8, 2018

Copy link
Copy Markdown

what's apply scenarios?

@compilelife

Copy link
Copy Markdown

nice hack, and fun, but just fun

@cedriczirtacic

Copy link
Copy Markdown

And Perl?

#ifndef C
$_=$0,s/\.c$//,print`gcc -DC -o $_ $0 && ./$_; rm -f $_`;
__END__
#endif
#include <stdio.h>

int main() {
    puts("Hello World!");
    return 0;
}

@torarnv

torarnv commented Aug 8, 2018

Copy link
Copy Markdown
//usr/bin/env clang++ $0 -o ${o=`mktemp`} && exec $o $*
#include <stdio.h>
int main() {
    printf("Hello World!\n");
    return 0;
}

@scentoni

Copy link
Copy Markdown

Due to an issue described here there is a warning printed on macOS that can be remedied using

///$(which true);export MallocNanoZone=0;COMPILER_OPTIONS="-g -Wall -Wextra --std=c++17 -O1 -fsanitize=address,undefined";THIS_FILE="$(cd "$(dirname "$0")"; pwd -P)/$(basename "$0")";OUT_FILE="/tmp/build-cache/$THIS_FILE";mkdir -p "$(dirname "$OUT_FILE")";test "$THIS_FILE" -ot "$OUT_FILE" ||$(which clang++ || which g++) -xc++ $COMPILER_OPTIONS "$THIS_FILE" -o "$OUT_FILE" || exit;exec "$OUT_FILE" "$@"
#include <iostream>

int main() {
  std::cerr << "Hello, world!" << std::endl;
  return 0;
}

@jdarpinian

Copy link
Copy Markdown
Author

Thanks, I've incorporated some of your suggestions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment