Creating An Executable On The Fly...

Hi all...

Had an idea tonight which could really enhance shell scripting for me.
Yes I am aware there could be difficulties but......

Creating a C script inside the shell script to do a task, (a simple text print to stdout in
this example), compiling it on the fly, making sure it is executable and then calling it
as part of the script...

Of course one would have to develop and fully test the C code first before inserting it
into a shell script and there may be some difficulties on fairly complex C scripts to
insert into said shell script but nevertheless this looks mighty interesting...

This is using OSX 10.7.5, default bash terminal and for OSX users XCode will need
to be installed from the Apple site before "gcc" can be used as Apple do not include
this part of the OS as standard. It is free and takes little time to get it...

Not tried on Linux and other *NIX flavours but there is no reason why it will not work.

#!/bin/bash
# Embed_C.sh
> /tmp/cscript.c
> /tmp/cscript
echo "Create a C script..."
echo '/* Embed a C script and compile on the fly. */
#include<stdio.h>
main()
{
    printf("A simple text line as a test...\n");
}' > /tmp/cscript.c
cd /tmp
echo "Compile this new C script as the default a.out..."
gcc cscript.c
mv a.out cscript
echo "Rename and ensure it is executable..."
chmod 755 cscript
echo "Now call it..."
echo ""
./cscript
echo ""
echo "Done!..."
exit 0

Results:-

Last login: Tue Apr 15 18:58:08 on ttys000
AMIGA:barrywalker~> ./Embed_C.sh
Create a C script...
Compile this new C script as the default a.out...
Rename and ensure it is executable...
Now call it...

A simple text line as a test...

Done!...
AMIGA:barrywalker~> _

Enjoy the supreme flexibility of the shell...

Just asking, isnt chmod 755 cscript just setting 'ownerships' of the file, as in, who may access/execute the file.
Rather than chmod +x cscript which would make it executeable.

Or am i mixing something?

Hi sea...

Good point, just a quirk of mine...
As the working idea is released as Public Domain then the choice is yours...

I am not sure what use a shell-specific hard core executable would be to others
on any specific system hence I limited execution to the owner of said script...

I will remember next time... ;oD

The chmod utility does not set ownerships; it sets modes. Both of the above commands set the execute bits on for the file's owner, group, and for the world.

Furthermore, if the compilation was successful, the compiler will make a.out (or whatever output file was designated) executable. So, the chmod is unnecessary. (If the compilation was not successful, changing the mode won't make it execute successfully until you fix the source and rebuild it successfully.)

And, if there are other compilations that could be happening in parallel in the same directory (and to avoid an extra step, even if there aren't), it would be easier to replace:

echo "Compile this new C script as the default a.out..."
gcc cscript.c
mv a.out cscript
echo "Rename and ensure it is executable..."
chmod 755 cscript

with:

echo "Compile this new C script..."
gcc cscript.c -o cscript

or:

echo "Compile this new C script..."
make cscript
2 Likes

Having (a little) time in the train, trying to make it multi functional:

#!/bin/bash
#	Compile file from arg
#	Extension of: http://www.unix.com/os-x-apple-/246397-creating-executable-fly-post302898214.html
#
#	Variables
#
	src=/tmp/example.c				# Set default src file as example
#
#	Action
#
	if [ -z $1 ]					# No arg (codefile) is passed
	then 	touch $src				# Create empty file
		echo '/* Embed a C script and compile on the fly. */
#include<stdio.h>
main()
{
    printf("A simple text line as a test...\n");
}' 		> $src					# Redirect it to default src file
	else	# Check if it is in current path or somewhere else
		[ -f "$(pwd)/$1" ] && \
			src="./$1" || src="$1"		# Set var 'src' to passed argument
	fi
	out="${src/.c$/}"				# Remove '.c' extension for the outputfile
	echo -e "Compiling \"${src##*/}\" to $out..."		
	gcc "$src" -o "$out" || exit 1			# If build fails exit with failure  -- doesnt work  with 'spaced' path names :(
	"$out"						# Execute it, `"` if passed subfolders contain spaces
	exit 0						# Return successfully

Now edited at home on windows, took more time to write on the phone than expected... + copy-paste is a pain.
Going to try now (as if i had written all on the phone), gotta reboot to linux first though. :wink:

Have fun :slight_smile:

EDIT:
Script fixed now, saved as ~./local/bin/compile with execution flag set, it outputs as:
Beeing aware, no compile arguments would be passed as of now, thats up to you to change/add if desired.

[sea@P50 ~]$ compile
Compiling "example.c" to /tmp/example...
A simple text line as a test...
[sea@P50 ~]$ compile example2.c
Compiling "example2.c" to ./example2...
Just another test...
[sea@P50 ~]$