It can be made even simpler with a few small changes, by arranging for the C program to remove itself when it runs:
#! /bin/bash
# Create a temporary file name for the executable file:
TMP_PROGRAM_FILE="$(mktemp programXXXXXX)"
# Compile the embedded C program:
gcc -o "$TMP_PROGRAM_FILE" -x c - <<- END_OF_SOURCE
#include <stdio.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
int i;
puts("Hello, world! I am a pseudoportable C program.");
for (i = 1; i < argc; ++i)
{
printf("Argument %d: %s\n", i, argv[i]);
}
unlink("$TMP_PROGRAM_FILE");
return argc - 1;
}
END_OF_SOURCE
# Run the program delegating all the arguments:
./$TMP_PROGRAM_FILE $@
This will not work under Windows but does work under Linux. I haven't tested Mac, but believe it will work there, too. The change, of course, is that the C program now deletes itself.