-
Notifications
You must be signed in to change notification settings - Fork 4
Home
Directly born from redtamarin, as3shebang is a single executable that self contain all the goodness with much less hassle.
Ever been tempted to toy with redtamarin but didn't have the time to investigate more than that ?
as3shebang is here to solve that exact problem: one installer, one little rule to follow and nothing else should stop you ;).
Here a list of few quick facts and stuff about all that technology.
- AVM2 is the ActionScript Virtual Machine 2.0
- AVM2 is what interpret ActionScript Bytecode (ABC)
inside the Flash player and the AIR runtime - you create ABC files by compiling ActionScript 3.0 source code
-
Tamarin is the open source AVM2,
you can find it here: avmplus - Tamarin does not contain the sources
of the Flash or AIR API (no UI, no sound, no image, etc.) - Redtamarin is an open source project
- Redtamarin extends Tamarin with native code (C++)
for Windows, Mac OS X and Linux in 32-bit and 64-bit - Redtamarin provides a POSIX / C API
(stdlib, stdio, unistd, socket, etc.) - Redtamarin provides native classes
(Program, Runtime, OperatingSystem, etc.) - Redtamarin provides implementations of the Flash and AIR API
(ByteArray, Proxy, Workers, etc.) - Redtamarin produces shell executable: redshell
- Redshell can execute ABC, AS and SWF files
- a SWF file is a container of multiple ABC files
- you can merge the redshell with an ABC file
to produce a single independent executable - the Redtamarin API allow you to eval AS3 source code at runtime
As a developer, especially in open source, I have always been bothered by the barrier to entry that some projects impose right from the start, which sadly could discourage most people who just want to try something new without all the hurdle of building the thing from scratch.
Sure you can take the sources and build Redtamarin yourself, this is hard;
a bit easier is to download the Redtamarin SDK and install/configure the different environment variables, executables, etc., this is still complicated.
Even me, who know all that stuff from the inside out, I needed something simple, fast to install and easy to use right away.
I give you as3shebang :).
ATTENTION
from v0.9 to v1.0 things have changed a little
now as3shebang works for Windows, Mac OS X and Linux
see the install instructions in the README
As a Linux sysadmin now I can do that
$ wget https://github.com/Corsaair/as3shebang/releases/download/v0.9-1/as3shebang_0.9-1_amd64.deb
$ dpkg -i as3shebang_0.9-1_amd64.deb
Simply put, as3shebang is an ActionScript 3.0 source code of a dozen lines that is compiled
as3shebang.as -> as3shebang.abc
and embedded within the Redtamarin shell: redshell
redshell_dd + as3shebang.abc = as3shebang
It's only purpose is to be called by your shell environment by the way of the shebang line.
#!/usr/bin/as3shebang
A series of small hacks that work well together :p
-
a redtamarin executable need to use a special kind of arguments
myprogram a b c
would configure the redshell executable itself,
to configure your program you need to use--
, and so if you want to
passa, b, c
as arguments tomyprogram
you need to domyprogram -- a b c
that's why you need to write the shebang line like this#!/usr/bin/as3shebang --
and not like that#!/usr/bin/as3shebang
.
ATTENTION
from v0.9 to v1.0 things have changed a little
you don't need to use -- anymore
-
While executing a program with
redshell
you need to use--
to pass arguments to your program, it is not needed anymore with
the new projectors (standalone executable) used by as3shebang 1.0.0
now you can directly callmyprogram a b c
and it will work, so
the shebang line now is just#!/usr/bin/as3shebang
. -
ActionScript 3.0 source code do not support comments line starting with
#
the classic shebang line#!/something
will make the ActionScript compiler or interpreter
throw an error and block the whole flow of the program. -
as3shebang simply cut off the shebang line
we don't read it, we don't really care about it
it's only purpose is to use the shell mechanism
to put us inside the redshell at runtime. -
Redtamarin can evalute ActionScript 3.0 source code at runtime
yes you read that right, we do have aneval()
function
and this is exactly what as3shebang is using to "run" the script.
Because the scripts are evaluated at runtime you may encounter some glitches with imported classes or packages not recognised by the environment.
For example
#!/usr/bin/as3shebang
import C.errno.*;
var err:CError = new CError( "", 13 );
trace( err );
when you execute it $ ./test
you will get
VerifyError: Error #1014: Class CError could not be found.
at shell::Runtime$/eval()
at global$init()
a simple workaround is to use the any type *
for the variable
#!/usr/bin/as3shebang
import C.errno.*;
var err:* = new CError( "", 13 );
trace( err );
and now $ ./test
output correctly
CError: EACCES #13: Permission denied
Also, AS3 shell scripts containing the shebang line are incompatible to run with the redshell or to be compiled with ASC (ActionScript Compiler).
If the script above is named test, then running
$ ./redshell test
will simply fail with the following error
SyntaxError: test:1: Syntax error: Illegal character in input: #
or compiling
$ java -jar asc.jar -AS3 -import redtamarin.abc test
will output numerous compiler errors
[Compiler] Error #1093: Syntax error.
sample2, Ln 1, Col 1:
#!/usr/bin/as3shebang
^
[Compiler] Error #1093: Syntax error.
sample2, Ln 1, Col 3:
#!/usr/bin/as3shebang
..^
[Compiler] Error #1084: Syntax error: expecting identifier before in.
sample2, Ln 1, Col 9:
#!/usr/bin/as3shebang
........^
[Compiler] Error #1093: Syntax error.
sample2, Ln 1, Col 11:
#!/usr/bin/as3shebang
..........^
4 errors found
- You can execute ActionScript 3.0 shell scripts
- Support all the AS3 builtins and the Redtamarin API
see the documentation: http://docs.redtamarin.com/latest/ - full error stacktrace
- You can pass arguments to those AS3 shell scripts
- You can pipe string and binary
- You can run them as CGI scripts under Apache
as3shebang is compiled with the redshell debug debugger, if your shell script contain errors you will obtain a stacktrace
Example
#!/usr/bin/as3shebang
trace( "UNKNOWN = " + UNKNOWN );
when executed will output
ReferenceError: Error #1065: Variable UNKNOWN is not defined.
at global$init()[:2]
at shell::Runtime$/eval()
at global$init()
Example to pass arguments
#!/usr/bin/as3shebang
import shell.Program;
for( var i:uint = 0; i < Program.argv.length; i++ )
{
trace( "argv[" + i + "] = " + Program.argv[i] );
}
execute $ ./test a b c
and you will get
argv[0] = a
argv[1] = b
argv[2] = c
Attention, there are some subtle differenced compared to executing a script with redshell.
In Redtamarin, you can get arguments using Program.argv
or C.argv
and C.argc
,
and by default C.argv[0]
contains the name of your executed script (eg. Program.filename
).
ATTENTION
from v0.9 to v1.0 things have changed a little
we do some magic to the arguments :)
But with as3shebang, an AS3 shell script will read the first argument from Program.argv[0]
.
While as3shebang is read, we read the first argument Program.argv[0]
to find the shell script.
If you try to find the name of the executable with Program.filename
you will obtain "/usr/bin/as3shebang"
(the resolved path to the as3shebang executable).
When as3shebang interpret your shell script, if you try to find the name of the executable
with Program.filename
you will obtain the name of the shell script "./test"
(for example).
To obtain your AS3 shell script executable name
you will need to use a magic variable named scriptname
.
To obtain your AS3 shell script executable name
either use Program.filename
or C.argv[0]
.
For example
#!/usr/bin/as3shebang
import shell.*;
trace( "scriptname = " + Program.filename );
if you ran the command $ ./test
you will then obtain
scriptname = ./test
Another magic variable is as3shebang
which contains the version of the as3shebang executable
#!/usr/bin/as3shebang
trace( "as3shebang " + as3shebang );
this does not work anymore with v1.0.0
Instead, now you can detect if your program
is running as a shell script using Program.type
#!/usr/bin/as3shebang
import shell.*;
if( Program.type == ShellType.SCRIPT )
{
trace( "I'm a shell script" );
}
So, earlier I mentioned you can pipe string and binary, here how to do that.
$ touch sample1
$ chmod + sample1
$ nano sample1
#!/usr/bin/as3shebang
import C.stdio.*;
import flash.utils.ByteArray;
var bytes:* = new ByteArray();
var read:int = fread( bytes, 1024, stdin );
trace( "read " + read + " bytes" );
bytes.position = 0;
var flat:String = bytes.readUTFBytes( bytes.length );
trace( "----" );
trace( flat );
trace( "----" );
let's pipe into our program
$ cat sample1 | ./sample1
will output the following
read 314 bytes
----
#!/usr/bin/as3shebang
import C.stdio.*;
import flash.utils.ByteArray;
var bytes:* = new ByteArray();
var read:int = fread( bytes, 1024, stdin );
trace( "read " + read + " bytes" );
bytes.position = 0;
var flat:String = bytes.readUTFBytes( bytes.length );
trace( "----" );
trace( flat );
trace( "----" );
----
With stdio function you can read and write to/from stdin, stdout, stderr etc.
using a ByteArray
that will supports manipulating binaries and strings.
ATTENTION
from v0.9 to v1.0 things have changed a little
under Windows you will need to set the console
mode to binary withC.conio.set_binary_mode()
example
// if under Windows we set our console to binary
if( Runtime.platform == "windows" )
{
set_binary_mode( STDIN_FILENO, true );
}
to pipe a binary as input
$ cat image.png | ./yourprogram
just fread()
the stdin
.
to pipe a binary as output
$ ./yourprogram | xxd
(xxd for a nice hexdump)
just fwrite()
to stdout
.
You will find a fullblown example in the Redtamarin API documentation
under C.conio.set_binary_mode()
.
And last but not least, here how to run your AS3 shell scripts as CGI scripts under Apache.
Let's define a basic apache conf
<VirtualHost *:80>
ServerName www.foobar.com
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/foobar-error.log
CustomLog ${APACHE_LOG_DIR}/foobar-access.log vhost_combined
DocumentRoot /var/www/foobar/htdocs
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory "/var/www/foobar/htdocs/">
Options Indexes FollowSymLinks MultiViews Includes
AllowOverride All
Require all granted
Options +ExecCGI
<FilesMatch (.*)$>
SetHandler cgi-script
</FilesMatch>
</Directory>
</VirtualHost>
now in your htdocs directory create your shell script
$ touch index
$ chmod +x index
$nano index
#!/usr/bin/as3shebang
trace( "Content-Type: text/plain; charset=utf-8" );
trace( "" );
trace( "hello world" );
access http://www.foobar.com/index
from a browser
and you should get this
hello world