Shell y Scripts de Java🔗

jshell es la herramienta disponible en el JDK, desde la versión 9 de Java, que permite la evaluación de código de Java de manera interactiva, como si de un shell o interprete de comandos se tratara.

Una sesión en jshell sería, a manera de ejemplo:

[nihilipster@localhost:~]$ jshell
|  Welcome to JShell -- Version 11.0.8
|  For an introduction type: /help intro

jshell> var xs = List.of(10, 20, 30, 40, 50)
xs ==> [10, 20, 30, 40, 50]

jshell> /vars xs
|    List<Integer> xs = [10, 20, 30, 40, 50]

jshell> var ys = xs.stream().map(x -> 2 * x).collect(Collectors.toList())
ys ==> [20, 40, 60, 80, 100]

jshell> /vars ys
|    List<Integer> ys = [20, 40, 60, 80, 100]

jshell> xs.get(0)
$3 ==> 10

jshell> ys.get(0)
$4 ==> 20

jshell> $3 + $4
$5 ==> 30

jshell> $5
$5 ==> 30

jshell> /vars
|    List<Integer> xs = [10, 20, 30, 40, 50]
|    List<Integer> ys = [20, 40, 60, 80, 100]
|    Integer $3 = 10
|    Integer $4 = 20
|    int $5 = 30

jshell> /exit
|  Goodbye

En ella se puede observar lo siguiente:

  • Las expresiones y sentencias son aquellas ofrecidas por la instalación de Java a la cual pertenezca jshell. En este caso es a la versión 11 de Java.
  • Los comandos propios de jshell empiezan con /. Puede uno obtener una lista de los mismos mediante el comando /help.
  • El prompt de jshell es jshell> por default, aunque dispone de otros o bien la opción de configurarlo mediante el archivo $HOME/.java/.userPrefs/tool/JShell/prefs.xml.
  • Los resultados de la ejecución de expresiones y sentencias previas quedan almacenando en variables, conocidas como scratch variables, con nombres conformados por el carácter $ seguido de un número entero, así $3 almacena el valor 10, $4 el valor 20 y $5 el valor 30.
  • El comando /vars permite obtener información de una variable o bien de las variables disponibles en esta sesión.

Hasta aquí el comportamiento de jshell es similar a la de un interprete de comandos, sin embargo uno puede estar más familiarizado con la idea de un REPL, esto es: tener abierto un archivo en un editor de texto desde el cual escribir código y enviar (todo el archivo o extractos del mismo) al REPL, el cual se encarga de su evaluación e impresión de resultados.

A manera de ejemplo, con el editor de texto VIM y el plugin reply.vim:

vim-reply-jshell.jpg

Puede observarse del lado izquierdo un archivo con código de Java, sin respetar la estructura del lenguaje, y del lado derecho la ejecución de jshell. Otras opciones para VIM podrían ser: neoterm, vim-repl, vim-ripple y zepl.vim

Ahora bien, es posible almacenar tanto código de java como comandos propios de jshell en un archivo:

  • Suponiendo que se tiene el archivo script.jsh con el siguiente contenido:

    //usr/bin/env jshell --no-startup --feedback silent "$0" "$@"; exit $?
    
    import java.util.*;
    import java.util.stream.*;
    
    var xs = List.of(10, 20, 30, 40, 50);
    var ys = xs.stream().map(x -> 2 * x).collect(Collectors.toList());
    
    for (Integer x : ys) {
      System.out.println(x);
    }
    
    /exit
    
  • Se le dan permisos de ejecución para poder ejecutarlo desde la línea de comandos:

    [nihilipster@localhost:~]$ chmod +x script.jsh
    [nihilipster@localhost:~]$ ./script.jsh
    20
    40
    60
    80
    100
    

El proyecto jbang lleva esto último al punto de poder crear una aplicación para la línea de comandos.

Enlaces🔗