Miglioramento a shell() di Foundation

Ciao.

Condivido un mini componente in cui ho creato una miglioria di shell().
Come dice la documentazione di IDF riguard a shell():

  • Se il comando non può essere lanciato, oppure causa un errore, l’applicazione web continua senza ottenere alcuna segnalazione.
  • Per ottenere il risultato del processo, si consiglia di redirigere l’output del processo su un file di testo e di leggere il file dall’applicazione web.
  • In JAVA per lanciare il comando viene utilizzata la classe java.lang.Runtime, per ulteriori informazioni riferirsi alla documentazione del metodo Exec.

Un comando del tipo “C:\Temp\cartella di prova\test.bat” par1 par2 funziona correttamente sia in Java che in C#, utilizzando correttamente lo spazio come delimitatore di parametri.

In Java non è invece gestito correttamente un comando del tipo: “C:\Temp\cartella di prova\test.bat” “par 1e2” in quanto anche il parametro viene separato utilizzando gli spazi; questo secondo caso è invece gestito correttamente in C#.

====

Questo è alquanto limitante e a me ha fatto impazzire per mesi.

Alla fine mi sono messo a fare la shell() come volevo che fosse fatta.

Vi condivido con piacere un progettino in cui ho messo un’estrazione di un subset di un mio componente gigante. Ci sono varie classi, ma l’unica su cui porto la vostra attenzione è X, non c’entra con Twitter, ma sta per eXtended, siccome ci ho messo le mie versioni migliorate delle feature di inde io chiamo ad esempio X.messageBox, X.sleep, X.shell, quindi con una sola lettera richiamo la classe.

Nella fattispecie qui vedete X.shell(), che a differenza di shell() aspetta che ci sia dell’output sulla console e lo restituisce in modo sincrono.

Non sarà perfetta ma è un buon passo avanti rispetto a solo shell() che essendo asincrona non è molto pratica da usare in IDF.

Siccome shell() ha un problema in java linux potete notare che le chiamate su javalinux in realtà le faccio chiamando
/opt/qvm/bin/indenohupwrapper |1 INDESHLOG=|2

ovvero lo script indenohupwrapper serve a slegare (No Hangup) le chiamate a shell dal webserver, ho notato che inde su java/linux uccide le shell dopo un tot (non so riprodurlo a colpo sicuro ma so che il mio script risolve il problema definitivamente).

Diciamo che se IDF avesse una shellEx() che si comporta come la mia X.shell() sarebbe già ottimo.

Ora, se guardate il codice è un po’ arzigogolato anche perché ho estratto X.shell() da una libreria molto più grande, per il piacere di condividerlo con voi, spero sia utile.

Allego lo script indenohupwrapper che andrebbe messo sulla macchina linux dove si usa X.shell(), noi lo mettiamo in /opt/qvm/bin/, infatti questo path è hardcoded nel mio codice.

Potete scaricare da qui

uno zip che contiene un idp con webapp e componente (compilate la webapp e lanciate i comandi del menu, è tutto self explained).
il file indenohupwrapper da mettere in linux all’occorrenza.

Questa versione di shell oltre a essere sincrona consente anche di inserire virgoeltte nei comandi senza i limit di shell(), già questa è una feature fondamentale, di fatto X.shell ha un paramtero opzionale che accetta sync o async, passando async si comporta come x.shell ma almeno si possono passare virgolette senza remore.
Diciamo che chi ha mai usato shell() dovrebbe capire il perché ho fatto X.shell().

Spero sia utile.

Che ne pensate? Mi piacerebbe sentire il vostro feedback.
@paolo.giannelli se prendete spunto per shellEx() in IDF vi lascio tutti i diriitti!

Ciao e buon weekend lungo (se avete la fortuna di farlo)

9 Mi Piace

@f.faleschini grazie per la condivisione e rimando ai miei colleghi di Instant Developer un giudizio sul tuo lavoro, io sono proprio poco esperto nell’uso di questa funzione di Foundation.

Direi che comunque è interessante e soprattutto il fatto di poter scegliere se usarla sincrona o asincrona.

a me serviva perché ho fatto un componente per manipolare i pdf usando pdfcpu (che è un tool da command line che funziona sia in windows che in linux) e shell() da sola faceva davvero perdere troppo tempo, con X.shell() ne sono venuto fuori e lo uso in produzione. Per ora ho fatto solo split e merge pdf, ma a breve mi serve anche l’aggiunta di watermark. Confermo che X.shell() è molto più usabile di shell().

Ciao!

1 Mi Piace