LEZIONE del 16 Novembre

Molti comandi di manipolazione dei file di testo utilizzano un parametro con il quale l'utente può specificare in modo del tutto generale lo schema del pattern da identificare ed, eventualmente, modificare. Il meccanismo con il quale ciò avviene è noto col termine di espressione regolare. La caratteristica di tale metodo di rappresentazione è quello di fornire una simbolizzazione semplice e sintetica per qualunque pattern il comando debba identificare.

ESPRESSIONI REGOLARI

Le espressioni regolari rappresentano pattern per descrivere insiemi di stringhe che, analogamente alle espressioni aritmetiche, sono costruite combinando expressioni più semplici per mezzo di operatori. Molti comandi della shell di Unix, come grep e sed, riconoscono due differenti versioni della sintassi: base ed estesa. In alcuni casi non c'è differenza sulle funzionalità messe a disposizione; in altri casi, le espressioni regolari base sono meno potenti. La breve descrizione riportata nel seguito si riferisce al caso della sintassi estesa.

I blocchi costitutivi fondamentali si riferiscono alle espressioni regolari che caratterizzano il singolo carattere, la maggior parte dei quali sono espressioni regolari che rappresentano sè stessi, lettere e cifre compresi. I metacaratteri hanno un significato speciale: per poter rappresentare sè stessi vanno quotati facendoli precedere da uno backslash.

La ripetizione ha ordine di precedenza superiore alla concatenazione che, a sua volta, supera quello dell'alternativa. Per sovrascrivere tale regola è sufficiente chiudere entro parentesi le sottoespressioni incriminate.

Nelle espressioni regolari base i metacaratteri ?, +, {, |, ( e ) perdono il loro significato speciale per cui è necessario utilizzare la forma che impiega il backslash: \?, \+, \{, \|, ( e \). Poichè non tutti i comandi egrep riconoscono il metacarattere {, la portabilità degli script impongono di evitare tale simbolo nella definizione dei pattern, sostituendo ogni sua occorrenza con [{].

OSSERVAZIONI E SUGGERIMENTI

Dalla breve presentazione precedente segue che le Espressioni Regolari sono insiemi di caratteri e/o metacaratteri che nel S.O. UNIX, e non solo, sono impiegate per ottenere speciali comportamenti. Fra di essi, i più noti e più diffusi sono la ricerca e la manipolazione di testi. Infatti, l'operazione realizzata dalle espressioni regolari è quella di identificare (matching) un carattere o un insieme di caratteri all'interno di un testo o di una stringa. Nel seguito vengono riassunte le caratteristiche salienti.

Ambiente per l'Esecuzione Remota

Del meccanismo con il quale il webserver accede ai parametri passati dalla form del browser alla shell local si è già abbondantemente discusso nelle precedenti lezioni. Si ricorda che le variabili d'ambiente coinvolte sono REQUEST_METHOD and CONTENT_LENGTH e, nel caso venga usato il metodo POST, i parametri sono accessibili direttamente dallo standard input.

Nello script riportato nel seguito si evidenzia chiaramente il modo con cui tali parametri sono acquisiti. La QUERY_STRING si ottiene dallo standard input e su di essa si opera una semplice elaborazione mediante l'impiego di espressioni regolari con cui è immediato separare le sottostringhe, separate l'una dall'altra con il carattere "&" per poi applicare per ciascuna l'identificazione della parte nome come variabile di shell a cui assegnare la parte valore. Anche in questo caso l'impiego delle espressioni regolari rende il processo assai semplice

#!/bin/bash
#   Synopsis : eval `cgiparse -init`
# extraction of the parameters passed to the shell by an HTML page

PREFIX="FORM_";

  function DoParse() {
    IFSOLD=$IFS;
    IFS="&";
    for ARG in $1; do
      NAME=`echo $ARG | sed -e 's/=.*$//'`;
      VALUE=`echo $ARG | sed -e 's/^.*=//'`;
      echo "${PREFIX}$NAME=${VALUE}";
    done
    IFS=$IFSOLD;
  }

if [ `echo $1 | egrep -e "-"` ] > /dev/null; then
  ACTION="`echo $1 | sed s/-//`"
else
  echo "no action to execute";
  exit 2
fi

if [ "$REQUEST_METHOD" = POST ]; then
  QUERY_STRING=$( head --bytes="$CONTENT_LENGTH" );
fi
 
case $ACTION in
  init) DoParse "${QUERY_STRING}" ; exit 0 ;;
  form) exit 0 ;;
  *) echo "no such an option"; exit 2 ;;
esac

CGI Parsing rivisitato

La chiamata dello script precedente col comando `eval cgiparse -init` consente di realizzare immediatamente le assegnazioni implicite nel passaggio dei parametri alla shell.

Nella rivisitazione dell'esempio dell'agenda telefonica viene evidenziato il meccanismo del passaggio dei paramtri emulandolo con una " mail" trasmessa dal browser verso il webserver. Così, partendo dal rendering dell'accesso remoto ad un'agenda telefonica è possibile tracciare in dettaglio i vari passaggi.

Affinchè la simulazione possa effettivamente funzionare è sufficiente lanciare lo script cgi utilizzando il comando bash implementato di seguito. Naturalmente è necessario attivare la posta locale con trasporto sendmail e, inoltre, modificare la pagina HTML originale in modo da attivare uno "javascript" che trasformi l'azione di submit della form in una attivazione del client di posta elettronica.

#!/bin/bash
#  Synopsis: xlaunch [-opt] cgi-script usermail

case "$#" in
0) echo "Usage: launch [-opt] cgi-script usermail";
   exit 2 ;;
1) echo "Insufficient arguments";
   exit 1 ;;
2) CGI_SCRIPT="$1";
   USERMAIL="/var/mail/$2";;
3) if [ `echo "$1" | grep -e "-"` ]; then > /dev/null
     OPT=`echo "$1" | sed 's/-//'`;
     CGI_SCRIPT="$2";
     USERMAIL="/var/mail/$3";
   else
     echo "Option required";
     exit 3
   fi ;;
esac

#TraceF=0;  do not uncomment this line

case $OPT in
d) TraceF=1 ;;
*) ;;
esac

ARGSFILE=`grep -e QUERY_STRING $USERMAIL | sed 's/^.\{1,12\}=//'`
WC=(`echo $ARGSFILE | wc -c`);
let "CONTENT_LENGTH = ${WC[0]} + 2";
REQUEST_METHOD=POST

export REQUEST_METHOD
export CONTENT_LENGTH

if [ "${TraceF:0}" ]; then
  echo "**********************************************************"
  echo "REQUEST_METHOD=$REQUEST_METHOD"
  echo "CONTENT_LENGTH=$CONTENT_LENGTH"
  echo "QUERY_STRING:<$ARGSFILE>"
  echo "**********************************************************"
fi

echo $ARGSFILE | ${CGI_SCRIPT}

RETVAL=$?
exit $RETVAL

Lancio dell'Ambiente per l'Esecuzione Remota