« 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é
Aucun résumé des modifications
Aucun résumé des modifications
Ligne 86 : Ligne 86 :
It is suggested to try, copy, adapt these examples 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&nbsp;file is similar&nbsp;to a standard bash file. Just replace the shebang&nbsp;: <span style="font-family:courier new,courier,monospace;">'''#!/usr/bin/bashj'''</span>&nbsp;instead of <span style="font-family:courier new,courier,monospace;">'''#!/bin/bash'''</span>.

Several families of java methods & fields may be called

*Those defined in the beginning of the running bashj&nbsp;script itself, between a line containing&nbsp;<span style="font-family:courier new,courier,monospace;">'''#!java&nbsp;'''</span>and a line containing<span style="font-family:courier new,courier,monospace;">'''&nbsp;#!bashj'''</span>. Java methods are defined there without package name and without class name. The implicit class name is "'''j'''". So a function&nbsp;public static <span style="font-family:courier new,courier,monospace;">int factorial(int n)</span> may be called in the script bash body as&nbsp;'''j.factorial(int)!'''
*Those present in the standard java packages&nbsp;'''java.lang.System'''&nbsp;&nbsp;and '''java.lang.Math'''&nbsp; (possibly more later if requested).&nbsp;
*The control methods provided by the bashj server (they write on stdout):
<div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">u.info()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# simple info provided by the running bashj server</span></div> <div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">u.status()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# detailed info provided by the running bashj server</span></div> <div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">u.classes()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # classes accessible using bashj</span></div> <div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">u.classes(String grep)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# filtered classes accessible using&nbsp;bashj</span></div> <div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">u.methods()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# methods accessible using bashj</span></div> <div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">u.methods(String grep)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# filtered methods accessible using&nbsp;bashj</span></div> <div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">u.fields()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# fields&nbsp;accessible using&nbsp;bashj</span></div> <div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">u.fields(String grep)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# filtered fields&nbsp;accessible using&nbsp;bashj</span></div>
Methods may&nbsp;be called with or without package prefix, with the same result&nbsp;:
<div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">echo&nbsp;Math.hypot(3.0,4.0)</span></div> <div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">echo java.lang.Math.hypot(3.0,4.0)</span></div>
The first one is the most readable and recommended.

The java call produces a bash variabale wich my be used in the usual ways:
<div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">echo&nbsp;Math.hypot(3.0,4.0)</span></div> <div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">HYPOT =&nbsp;Math.hypot(3.0,4.0)</span></div>
Void java methods should be called using this syntax:
<div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">: server.info()</span></div>
Methods in the java section are public by default. The two next lines are equivalent:
<div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">public static void fibo(int n) {...}</span></div> <div style="background: rgb(238, 238, 238); border: 1px solid rgb(204, 204, 204); padding: 5px 10px; margin-left: 40px;"><span style="font-family:courier new,courier,monospace;">static void fibo(int n) {...}</span></div>
== Configuration ==
== Configuration ==


Ligne 127 : Ligne 105 :


The bashj script may be called as interpter, or interactively for various actions. Use bashj -help to&nbsp;see this:
The bashj script may be called as interpter, or interactively for various actions. Use bashj -help to&nbsp;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&nbsp;: server status<br/> &nbsp;-stop&nbsp;: stops the server<br/> &nbsp;-restart&nbsp;: restart server<br/> &nbsp;-out&nbsp;: show server stdOut<br/> &nbsp;-err&nbsp;: show server stdErr<br/> &nbsp;-u&nbsp;: list utility methods from class u (bashj.u)</div> <div style="background:#eee;border:1px solid #ccc;padding:5px 10px;">&nbsp;classes <filter>&nbsp;: lists classes accessible to bashj clients<br/> &nbsp;methods <filter>&nbsp;: lists methods accessible to bashj clients<br/> &nbsp;fields &nbsp;<filter>&nbsp;: lists fields &nbsp;accessible to bashj clients</div> <div style="background:#eee;border:1px solid #ccc;padding:5px 10px;">&nbsp;<simple function expression>&nbsp;: evaluates argument using bashjServer<br/> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; example:&nbsp; &nbsp; bashj "Math.hypot(3.0,4.0)"</div>
<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&nbsp;: server status<br/> &nbsp;-stop&nbsp;: stops the server<br/> &nbsp;-restart&nbsp;: restart server<br/> &nbsp;-out&nbsp;: show server stdOut<br/> &nbsp;-err&nbsp;: show server stdErr</div> <div style="background:#eee;border:1px solid #ccc;padding:5px 10px;">&nbsp;classes <filter>&nbsp;: lists classes accessible to bashj clients<br/> &nbsp;methods <filter>&nbsp;: lists methods accessible to bashj clients<br/> &nbsp;fields &nbsp;<filter>&nbsp;: lists fields &nbsp;accessible to bashj clients</div> <div style="background:#eee;border:1px solid #ccc;padding:5px 10px;">&nbsp;<simple function expression>&nbsp;: 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 20 juin 2018 à 11:25

What ?                   

The bashj project is hosted on sourceForgebashj is an extended bash allowing to use java libraries, functions and code from bash scripts.

Bashj.png
Bashj.png

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.994 (june 2018) is still a beta release... Release 1.0 expected july 2018 !

This page is an introduction to bashj, with general notes and installtion guide.

There is also a bashj_programming_guide page.

To bash developers, bashj brings

  • Readability in the java segment (OO style coding)
  • JVM efficiency for CPU intensive components
  • double values variable and evaluation functions
  • Math tools
  • Swing UI tools
  • Inter process tools between multiple bash process (and java process)
  • Host registry
  • ...

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). I was also frustrated by the strange and numerous coding conventions necessary to perform simple bash tasks. So I decided to set up and use this bashj 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 ?

Bashj flows.png

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 JDK (9+) (JRE is not enough)
  • only public static methods (and public static fields) may be called 
  • only 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 
  • These characters  ® ©  have specific usage within 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.

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
 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

  • ? Allow more than 1 occurence of calls for given method
  • ? Create a installable package for debian distribs.
  • ? Organize the bashj server as a Linux service