Autore Topic: intercettare lo standard output di un comando (quello che vedo nella console)?  (Letto 580 volte)

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Non e' la prima volta che affrontiamo l'argomento, ma devo dire che ogni volta la soluzione 'e sempre un escamotage.

Quando lanciate un comando shell, di solito, ottenete lo standard output nella finestra "console" di gambas.

Ora la mia esigenza e' intercettare questo output e agire di conseguenza ....

Nello specifico il comando che lancio e':
Codice: [Seleziona]
Shell "melt -profile dv_pal -timings -consumer decklink:0 terminate_on_pause=1 \x22" & Path & "\x22" For Write As "Osserva"

con:
Codice: [Seleziona]
Public Sub Osserva_Read()

  Dim sLine As String

  Read #Last, sLine, -256

  Debug sLine

End

Public Sub Osserva_Write()
 
  Debug "-osserva-"
 
End

che non danno segni di vita (il processo lanciato nella shell gira in background ....)

notare che se invece il comando che lancio e':
Codice: [Seleziona]
Shell "melt -profile dv_pal -timings -consumer decklink:0 terminate_on_pause=1 \x22" & Path & "\x22" For Read As "Osserva"

la riproduzione del video (melt e' un player video) non parte proprio ...

PS: la cosa interessante e' che usando il comando:
Codice: [Seleziona]
dmesg -wH
questo comando guarda a partire dalla coda gli eventi del vostro sistema (quindi magari mettete e smontate chiavette per avere degli eventi ....)

il ritorno c'e l'ho .... e' come se melt uscisse su un'altra console ... e' possibile?
« Ultima modifica: 11 Aprile 2018, 16:13:56 da allegfede »
se corri, morirai stanco (motto degli sniper)

Offline Gianluigi

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 4.158
  • Tonno verde
    • Mostra profilo
Probabilmente dico una idiozia perché io shell non l'ho mai usato, ma se invece di Shell usassi Exec?

 :ciao: :ciao:
nuoto in attesa del bacio di una principessa che mi trasformi in un gambero azzurro

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.316
  • Ne mors quidem nos iunget
    • Mostra profilo
In via generale, quando un programma lanciato con (la maledetta) Shell restituisce un unico flusso di dati, è sufficiente usare la parola-chiave "To" per raccoglierli.

Un semplicissimo esempio è dato dal comando "ls":
Codice: [Seleziona]
Public Sub Main()

  Dim s As String

  Shell "ls /tmp" To s
  Print s

  Print Split(s, "\n")[1]

End
Insomma, in questo caso l'invio di dati e la loro intercettazione si esauriscono in un solo momento.


Quando invece il "processo", avviato con Shell, invia nel tempo uno o più dati, questi possono essere intercettati solo ponendo in "osservazione" la viariabile handle del processo aperto:
http://www.gambas-it.org/wiki/index.php?title=Lettura_dati_da_un_Processo_e_scrittura_dati_in_un_Processo

Un paio di esempi possono essere questi:
http://www.gambas-it.org/wiki/index.php?title=Intercettare_i_dati_del_mouse_dal_suo_file-device#Apertura_del_file-device_medinate_la_Classe_Process
http://www.gambas-it.org/wiki/index.php?title=La_gestione_dei_dati_Midi_senza_l%27uso_delle_funzioni_di_Alsa#Ricezione_mediante_Process
« Ultima modifica: 11 Aprile 2018, 20:34:54 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
ragazzi, in realta' appena postato il thread mi sono accorto di quale potrebbe essere il problema.

Infatti con l'esempio di dmesg -wH , il codice per intercettare l'output funziona, ma non con melt (e suppongo neanche con ffmpeg).

Questo penso derivi dal fatto che in realta' entrambi i comandi (programmi) lanciano un secondo thread che fa' l'elaborazione vera e propria, che a sua volta scrive sullo standard output.

In questo modo, il povero gambas intercetto l'output del Padre, ma ovviamente non ha controllo sul figlio ........ argghhhhhhh

penso che mi dovro' rassegnare e convertire il wrapper di MLT dal python a gambas.

dura, la vedo dura .....
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.316
  • Ne mors quidem nos iunget
    • Mostra profilo
Questo penso derivi dal fatto che in realta' entrambi i comandi (programmi) lanciano un secondo thread che fa' l'elaborazione vera e propria, che a sua volta scrive sullo standard output.

In questo modo, il povero gambas intercetto l'output del Padre, ma ovviamente non ha controllo sul figlio
Sì, a volte ci si trova dinanzi a questa situazione... davvero difficile da risolvere.  :-X



dura, la vedo dura .....
A mio parere la gestione dello standard output è uno degli argomenti più complessi !
Ce ne ho perse di ore !    :hatecomputer:

Ancor più complicato è raccogliere quanto è stato già scritto in console/terminale !!!   :hard:
« Ultima modifica: 11 Aprile 2018, 20:34:05 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.316
  • Ne mors quidem nos iunget
    • Mostra profilo
Proprio ieri è stata aperta questa discussione nel forum spagnolo:

http://www.gambas-it.org/smf/index.php?topic=6221.0
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
Interessante, ma non vorrei mostrare agli utenti la console, ma estrarre i dati dalla stessa per delle elaborazioni in background (sapere lo stato della riproduzione di un file).

A questo punto pensavo di bypassare il problema passando da un oggetto "terzo" ed esterno (con il mio video convertitore batch basato su ffmpeg ho fatto in  modo simile.)

ovvero, passare per un file esterno (un log) che scrive il processo lanciato dalla shell e che il programma gambas legge ed interpreta.

Ma mentre ffmpeg ha la possibilita di generare autonomamente un file di statistiche (e' una opzione del programma), in questo caso ho dovuto usare le redirezioni tipiche della bash linux.

in pratica il comando con redirezione e':
Codice: [Seleziona]
If Exist(User.Home & "/mlt_output.log") Then Kill (User.Home & "/mlt_output.log")

melt -profile dv_pal -timings -consumer decklink:0 terminate_on_pause=1 path_del_file_video  &> /home/utente/mlt_output.log

ed in un timer leggo il contenuto con un tail o similare:
Codice: [Seleziona]
tail -n 1 mlt_output.log

che (lanciando tutto da shell) mi tira fuori qualcosa del genere (varia man mano che interpreta il file):
Citazione
| 2018-04-12 12:45:39.739 | consumer_decklink.cpp:803: T(render)=8340 us

ora pero' la cosa e' ancora piu' strana, perche' se le stesse IDENTICHE cose le lancio dal mio programma gambas:
Codice: [Seleziona]
comando = "melt -profile dv_pal -timings -consumer decklink:0 terminate_on_pause=1 " & Path & "  &> " & User.Home & "/mlt_output.log"

Shell comando

il timer dove ho messo la lettura del file, mi ritorna il NULLA (giustamente, visto che ho cancellato il file prima di lanciare la NUOVA riproduzione)
se corri, morirai stanco (motto degli sniper)

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
allora, per ora l'unica cosa che sono riuscito ad ottenere (e solo con l'uso di "For Output" e' la possibilita' di MANDARE comandi al player/comando_shell.

Codice: [Seleziona]
' Gambas class file

Public comando As String = "melt -profile dv_pal -timings -consumer decklink:0 terminate_on_pause=1 /home/v1p3r/Video/2016-11-27\\ Leathernecks\\ camp/FHD0005.MOV &> /home/v1p3r/test.log"
'Public comando As String = "melt -profile dv_pal -timings -consumer decklink:0 terminate_on_pause=1 /home/v1p3r/Video/2016-11-27\\ Leathernecks\\ camp/FHD0005.MOV"

Public logfile As String

Public processo As Process


Public Sub Button1_Click()

  processo = Shell comando For Output

End

Public Sub Button2_Click()

  Write #processo, "q"

End

impossibile estrarre dati o avere statistiche ....
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.316
  • Ne mors quidem nos iunget
    • Mostra profilo
Eh... ma melt qua chi lo usa ?
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
solo io suppongo :-(
se corri, morirai stanco (motto degli sniper)

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.316
  • Ne mors quidem nos iunget
    • Mostra profilo
...appunto.
Pertanto non c'è nessuno che può provarlo.  :-\
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline allegfede

  • Gran Maestro dei Gamberi
  • *****
  • Post: 738
    • Mostra profilo
se consideri che anche lo sviluppatore stesso mi ha fatto marameo ..  dicendomi di passare al C++ :'(

arrrgghhhh
se corri, morirai stanco (motto degli sniper)