SCript-Executing Script

#software

04 Feb 2017

Run scripts directly, with transparent compilation


Introduction

SCES (SCript-Executing Script) is, simply put, a script that runs others scripts, however, it’s designed to work with languages that are not usually executable directly, but compiled.

For example, look at this hello world code written in C:

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello, world!\n");
    return 0;
}

Normally, if you want to run this code, you would compile it and run. But what if you really really want to run it without having to worry about the compilation, and you don’t want to delete the compiled program when you finish with it?

Just add a shabang to the first line of the program (like you would do it on a Python script).

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

int main(int argc, char *argv[])
{
    printf("Hello, world!\n");
    return 0;
}

you can then run it directly from the command line

$ chmod +x my_script.c
$ ./my_script.c
Hello, world!

Supported languages and features

The following languages are currently supported:

sces uses a combination of techniques to make the script behave as an executable, including:

Installation

Just download the script from the link at the top of the page, copy the script in a location of your choice (e.g. /usr/bin/sces) and make it executable.

To use it, add the shabang that points to the installation path.

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

int main(int argc, char *argv[])
{
    printf("Hello, world!\n");
    return 0;
}

you can pass additional arguments to the compiler by adding an exclamation mark (!) after the shabang, followed by the arguments. For example, to disable optimization for C/C++, add this line on top of the file

#!/usr/bin/sces ! -O0
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello, world!\n");
    return 0;
}

The script will automatically remove the exclamation mark and pass the -O0 string to GCC. Unlimited arguments can be provided, as long as they are on the same line.

For some languages (most actually), various text editors and syntax highlighter will give syntax errors on the first line. Do not worry! SCES will remove the first line and replace it with an empty line (to preserve line numbers in the code) before passing it to the compiler.

For certain languages, you might need additional dependencies.

C/C++

SCES expect GCC (for c) and g++ (for c++) to be installed. On Debian-based systems, if not already installed, it should be enough to install the apt package build-essential.

SystemC

On Debian, the packages libsystemc and libsystemc-dev must be installed (more information on this blog post). Additionally, a reference to the SystemC library must be given in the shabang

#!/usr/bin/sces ! -lsystemc
SC_MODULE(mymodule)
{
    // ...
}

C#

Mono must be installed, on Debian install the following packages:

sudo apt install mono-mcs libmono-system-windows-forms4.0-cil binfmt-support

Then, the system must be configured to run .exe files directly with mono (./my_exe.exe instead of mono my_exe.exe). This is done by appending a line to the binfmt configuration file.

echo ":CLR:M::MZ::/usr/bin/mono:" | sudo tee /etc/binfmt.d/mono.conf

Additionally, to run WinForms applications, you need to specify the correct .NET Framework assemblies to the compiler.

#!/usr/bin/sces ! -r:System.Windows.Forms.dll -r:System.Drawing.dll
using System;
using System.Windows.Forms;

static class Program
{
    static void Main()
    {
        MessageBox.Show("Hello, world!");
    }
}

ECL

Install ECL according to the guide I’ve posted. Make sure that the ecl is in a directory in the $PATH environment variable.

How does it work?

The mechanism is quite simple. By adding the correct shabang (#!/usr/bin/sces), sces is used to execute the script, so its path received as an input argument. From the extension, sces understand what file it is and has a routine for each programming language:

  1. sces gets the source file, replacing the first line with an empty line (because # is not a valid comment or token in many languages) so to preserve line numbering in case of errors
  2. the code is compiled (if necessary by the language). The executable is stored in /tmp
  3. if there are no error, the shell is forked (using exec) to the executable just created. argv[0] is replaced to the original script name and all other arguments are passed, so the execution of the script is completely transparent
  4. at the end of execution, the script return code is returned and the temporary files are deleted

On a relatively fast PC, the execution is very fast as if it was running the script in real time. Of course this program is not designed for performance, just as a tool to quickly run small scripts without having to deal with compilations and executable. You only need the source file and you can neatly “execute” it.

Last edit: 16/09/2024