« Project bashj : a bash mutant with java support » : différence entre les versions

De Lillois Fractale Wiki
Aller à la navigation Aller à la recherche
Contenu ajouté Contenu supprimé
(Project bashj : bash java hybrid interpreter allowing java calls from bash with a stunning speed.)
Aucun résumé des modifications
Ligne 123 : Ligne 123 :
Please contact [mailto:fil@gonze.org fil@gonze.org] for support, remarks, suggestions,...
Please contact [mailto:fil@gonze.org fil@gonze.org] for support, remarks, suggestions,...


=== bashj interactive commands ===

The bashj script may be called as interpter, or interactively for various actions. Use bashj -help to see this:
<div style="background:#eee;border:1px solid #ccc;padding:5px 10px;">[bashj] Possible interactive command arguments&nbsp;are:<br/> &nbsp;-help<br/> &nbsp;-install<br/> &nbsp;-uninstall<br/> &nbsp;-status : server status<br/> &nbsp;-stop : stops the server<br/> &nbsp;-restart : restart server<br/> &nbsp;-out : show server stdOut<br/> &nbsp;-err : show server stdErr<br/> &nbsp;-u : list utility methods from class u (bashj.u)</div> <div style="background:#eee;border:1px solid #ccc;padding:5px 10px;">&nbsp;classes <filter> : lists classes accessible to bashj clients<br/> &nbsp;methods <filter> : lists methods accessible to bashj clients<br/> &nbsp;fields &nbsp;<filter> : lists fields &nbsp;accessible to bashj clients</div> <div style="background:#eee;border:1px solid #ccc;padding:5px 10px;">&nbsp;<simple function expression> : evaluates argument using bashjServer<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; example:&nbsp; &nbsp; bashj "Math.hypot(3.0,4.0)"</div>
=== Installed Files ===
=== Installed Files ===



Version du 16 juin 2018 à 17:58

Bashj.png
Bashj.png

 

 

 

 

What ?

The bashj project is hosted on sourceForge.

bashj is an extended bash allowing to use java libraries, functions and code from bash scripts.

Coding examples are visible at the end of this page.

The bashj code combines

  • java performance and readability
  • bash power and versatility

Current version 0.991 (june 2018) is still a beta release... Release 1.0 expected july 2018 !

Why ?

Java and bash are often partners in software projects.

Personnally I used both of them widely. Being rather lazy, I tried to minimize the number of necessary techonologies in my projects. These two covered 99% of my needs together. Java is perfect to translate concepts into software. But bash is necessary for various OS level tasks, like process control, deployment ... But I was frequently disappointed by the incapacity to reuse java results and expertise within scripts (this was only possible with heavy java process launching, and main() entry points). So I decided to set up and use this tool.

In terms of genetics, consider bashj as a bash mutant, whose genome has been loaded with wide portions of the java genome. 

Their possible interactions are numerous but limited in terms of integration.

With this project, any script is given the capacity to quickly and directly call java methods without creating new OS processes.

How ?

A bashj server (a java background process)  communicates with bash scripts (considered as clients).

Dedicated functions are internally defined, and used from bash script clients to request server actions.

The communication uses mainly TCP connections.

This may be also be seen as a kind of bash preprocessor : bash itself is called by the bashj process.

Requirements and limitations

  • bash scripts only (not usable interactively)
  • Linux only (kernel 4.*+)
  • java (9+)
  • requires javac (JDK installed)
  • only public static methods (and public static fields) may be called 
  • ony methods with primitive types (including String) as parameters and return value (neither array, nor collections). Varargs are supported by bashj.
  • no embedded invocations of java methods 
  • This character is used as special delimiter (internally) by bashj and may not be used in bashj sources

Installation

Follow carefully these steps:

  1. create a directory  :  sudo mkdir -m=777  /var/lib/bashj/
  2. download from  sourceForge the bashjInstall-version.jar installation file and move it in this directory
  3. running a bash session, go to the installation directory : cd /var/lib/bashj/
  4. run  : jar xvf bashjInstall-version.jar
  5. run : chmod +x bashj
  6. run  : sudo ./bashj -install

For the uninstallation:

  1. cd 
  2. sudo /var/lib/bashj/bashj -uninstall 

Check, try and test

Various bashj scripts examples are in /var/lib/bashj/example/.

bashj "Math.cos(1.0)"               # check that the bashj interpreter operates
cd /var/lib/bashj/example/          # going to the example directory
ls                                  # view list of examples
cat javaLang                        # having a look at the code
./javaLang                          # running the code
cat check
./check
./all                               # run all examples - shows execution speed

The same may be realized for all example scripts.

It is suggested to try, copy, adapt these examples scripts.

bashj syntax rules and java calls

The bashj interpreter only works for scripts. It may not be used for an interactive session.

A bashj file is similar to a standard bash file. Just replace the shebang : #!/usr/bin/bashj instead of #!/bin/bash.

Several families of java methods & fields may be called

  • Those defined in the beginning of the running bash script itself, between a line containing #@java and a line containing #@bash. Java methods are defined there without package name and without class name. The implicit class name is "j". So a function public static int factorial(int n) may be called in the script bash body as j.factorial(int).
  • Those present in the standard java packages java.lang.System  and java.lang.Math  (possibly more later if requested). 
  • The control methods provided by the bashj server (they write on stdout):
u.info()                       # simple info provided by the running bashj server
u.status()                     # detailed info provided by the running bashj server
u.classes()                    # classes accessible using bashj
u.classes(String grep)         # filtered classes accessible using bashj
u.methods()                    # methods accessible using bashj
u.methods(String grep)         # filtered methods accessible using bashj
u.fields()                     # fields accessible using bashj
u.fields(String grep)          # filtered fields accessible using bashj
  • Those provided as utilities as part of bashj. They are also accessible with a class name "u", for instance u.toUpperCase(String) or yellow(String). The list is available using bashj -u.
  • Those present in jars put by the user in the subdirectory jarlib.

Methods may be called with or without package prefix, with the same result :

echo Math.hypot(3.0,4.0)
echo java.lang.Math.hypot(3.0,4.0)

The first one is the most readable and recommended.

The java call produces a bash variabale wich my be used in the usual ways:

echo Math.hypot(3.0,4.0)
HYPOT = Math.hypot(3.0,4.0)

Void java methods should be called using this syntax:

: server.info()

Methods in the java section are public by default. The two next lines are equivalent:

public static void fibo(int n) {...}
static void fibo(int n) {...}

Configuration

No configuration is necessary.

However it is possible for the user to put various jar files under the jarlib/ directory.

All public static methods and all public static fields defined in these classes will be available in the bashj interpreter.

They should be called as indicated above.

Annexes

Support

Please contact fil@gonze.org for support, remarks, suggestions,...

bashj interactive commands

The bashj script may be called as interpter, or interactively for various actions. Use bashj -help to see this:

[bashj] Possible interactive command arguments are:
 -help
 -install
 -uninstall
 -status : server status
 -stop : stops the server
 -restart : restart server
 -out : show server stdOut
 -err : show server stdErr
 -u : list utility methods from class u (bashj.u)
 classes <filter> : lists classes accessible to bashj clients
 methods <filter> : lists methods accessible to bashj clients
 fields  <filter> : lists fields  accessible to bashj clients
 <simple function expression> : evaluates argument using bashjServer
              example:    bashj "Math.hypot(3.0,4.0)"

Installed Files

The files are installed under /var/lib/bashj/, and include:

  • bashjInstall.jar (a jar containing all bashj required files)
  • bashj (the central script, including the command interpreter - a link is created in /usr/bin)
  • bashjEval & bashjAdmin (auxiiary scripts)
  • bashjServer.jar (a jar containing the compiled java class bashj.server.class)
  • README (a readme file - short intro to this wiki page)
  • classes/ bashSrc/ and bashjSrc (subdirectories with transient working contents)
  • jarlib/ (a subdirectory with the jars choosen by the user to make the involved classes available  to bashj)
  • example/ (a subdirectory with various example scripts (executable files))

Tech notes

The execution time of bashj  is excellent due to

  • TCP efficiency
  • use of shared system file
  • in-memory java compiling
  • cache-based java compiling
  • JVM global efficiciency

Speed notes

Simple tests (on a 2018 standard machine) indicate that a basic java method call requires less than 4 msec. This probable depends on TCP config parameters.

The startup time for a bashj script is around 25 msec.

For calls involving heavy CPU load, the execution delay is exactly the same as in a normal JVM.

Future Improvements

  • ? Create a installable package for debian distribs.
  • ? Organize the bashj server as a Linux service

Script coding examples

#!/usr/bin/bashj
#@java
static int factorial(int n) 
{if (n<=0) return(0);
 if (n==1) return(1);
 return(n*factorial(n-1));}
#@bash
echo j.factorial(10)

 

#!/usr/bin/bashj
#@java
static void hello()
{u.p("Hello, bashj  world !");
 u.p("This code is executed in a JVM "+System.getProperty("java.version"));
 u.p("But it is processed through bashj and finally bash");}
#@bash
 : j.hello()

 

#!/usr/bin/bashj
echo Math.cos(0.5)
echo Math.hypot(3.0,4.0)
echo System.getProperty("java.runtime.version")

 

#!/usr/bin/bashj
#@java
static String ax2_bx_c(double a,double b,double c)
{final double r=b*b-4*a*c;
 if (r<0.0) return("NoRoot");
 if (r==0.0) return(""+(-b/(a+a)));
 final double sq=Math.sqrt(r);
 return(""+(-b-sq)/(a+a)+" "+(-b+sq)/(a+a));}
#@bash
echo "... Delivers the roots of a quadratic equation"
A=1.0
B=-5.0
C=6.0
echo "... Solving $A X^2 + $B X + $C"
echo "... Roots are " j.ax2_bx_c($A,$B,$C)

 

#!/usr/bin/bashj
echo "bashj server utilities"
echo
 : server.classes()
echo
 : server.methods("bashj.u.")
echo
 : server.fields("ersion")
echo
 : server.info()

 

#!/usr/bin/bashj
echo "bashj string utilities"
echo
WORD=Bonjour
echo length of $WORD is u.strlen($WORD)
LETTER=u
echo index of $LETTER in $WORD is u.indexOf($WORD,$LETTER)
echo Uppercase u.toUpperCase($WORD)
echo Lowercase u.toLowerCase($WORD)