« Project bashj : a bash mutant with java support » : différence entre les versions
Aucun résumé des modifications |
Aucun résumé des modifications |
||
Ligne 39 :
== How ? ==
A bashj server (a java
A dedicated function (<span style="font-family:courier new,courier,monospace;">jsb()</span>) is internally defined. It is used from bash script clients to request server actions.
|
Version du 13 juin 2018 à 21:40
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
version 0.985 (june 2018) is still a beta release...
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).
A dedicated function (jsb()) is internally defined. It is used from bash script clients to request server actions.
The communication uses two named pipes (see also tech notes in annex).
All this may be also be seen as a kind of bash preprocessor.
Requirements and limitations
- bash scripts only (not usable interactively)
- Linux only
- java 9+
- requires javac (JDK installed, with compiler accessible as /usr/bin/javac)
- only public static methods 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
- Calling a bashj script from a bashj script (currently) not possible.
Installation
Follow carefully these steps:
- create a directory : sudo mkdir -m=777 /var/lib/bashj/
- download from sourceForge the bashjInstall.jar installation file and move it in this directory
- running a bash session, go to the installation directory : cd /var/lib/bashj/
- run : jar xvf bashjInstall.jar
- run : chmod +x bashj
- run : sudo ./bashj -install
For the uninstallation:
- cd
- sudo /var/lib/bashj/bashj -uninstall
Check, try and test
Various bashj scripts examples are in /var/lib/bashj/example/.
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 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):
- Those provided as utilities as part of bashj. They are accessible with a class name "u", for instance u.toUpperCase(String) or yellow(String). The list is available using server.methods("bashj.u").
- Those present in jars put by the user in the subdirectory jarlib.
Methods may be called with various equivalent syntax. The following lines (in a bashj script) provide the same result :
The first one is the most readable and recommended.
The java call produces a bash variabale wich my be used in the usual ways:
Void java methods should be called using this syntax:
Methods in the java section are public by default. The two next lines are equivalent:
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 before.
Annexes
Support
Please contact fil@gonze.org for support, remarks, suggestions,...
Installed Files
The files are installed under /var/lib/bashj/, and include:
- bashjInstall.jar (a jar containing all bashj required files)
- bashjInstall (an installation script) & bashUninstall
- bashjServer.jar (a jar containing the compiled java class bashj.server.class)
- bashj (a script, the command interpreter) (a link is created in /usr/bin)
- README a readme file (a short intro to this page)
- pipe/a subdirectory used for named pipes
- classes/ a subdirectory with transient compiled java classes
- 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
- named pipe efficiency
- use of shared system file
- in-memory java compiling
- cache-based java compiling
- JVM global efficiciency
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)