• BASH > zenity > progression d’un processus

      récupérer la sortie d’état
      -je lance l’encodage , lache le process et récupère le pid :

      ffmpeg -i entre.truc sortie.truc 2>/tmp/ffmpeg.log &
      PID=$!

      -je lance une boucle while tand que le process tourne pour creer une progress-bar pour zenity

      while [[ $(pidof ffmpeg)  = $PID ]]
      do
      	sleep .2
      	POURCENTAGE
      done | zenity --progress  --auto-close --title=Video2flv

      Et la le drame , j’ai besoin de connaitre l’état de sortie de ffmpeg pour afficher une boite de dialogue qui confirme ou infirme l’encodage !
      Pour le moment je regarde la derniere ligne du fichier log  :

      [[ $(tail -n 1 /tmp/Video2flv.log | grep overhead ) ]] && zenity --info --title=Video2flv --text="Encodage terminé !" || VIDEO2FLV_ERROR

      Mais ce n’est pas du tout ce que je souhaite , cela fonctionne bien sur mais je m’interroge sur la maniere de reccupérer l’etat de sortie d’un processus lâché comme cela , j’ai essayé avec wait , avec des tas de bidouille mais cela alourdie mon script et ne correspond pas à mes attentes !

      Donc ma question : comment reccupérer l’état d’un processus quelconques lâché de cette maniére ??
      Si les cadors du bash passe par là j’en serais heureux , il me reste beaucoup de chose à apprendre

      Bon ben je me répond :

      strace -p "$PID" -e trace=process -o  /tmp/traceff.log

      wait te donne bien l’état de sortie d’un processus donné.

      Par contre si ton but est de vérifier s’il est terminé ou non, ce n’est pas la même chose que récupérer son état de sortie, qui n’existe que si le processus est terminé. Pour vérifier qu’un processus n’est pas terminé, je n’ai pas mieux qu’un ps


      En fait le probleme de wait c’est ou le placer :

      Mon script ressemble a çà :

      function VIDEO2FLV_ERROR()
      {
      kill $PID
      zenity --error --title=Video2flv --timeout=1
      zenity --text-info --filename=/tmp/Video2flv.log --title=Video2flv  --width=800 --height=600
      exit 1
      }
      
      function POURCENTAGE()
      {
      sed -e 's/\r/\n/g' /tmp/Video2flv.log | grep time= | tail -n 1 | sed -e 's/frame/IMAGE/;s/fps/\nFPS/;s/q/\nQUALITEE/;s/size/\nPOID/;s/time/\nTEMPS/;s/bitrate/\nBITRATE/' | tr -d ' ' > /tmp/affichetout.txt
      
      . /tmp/affichetout.txt
      
      ACTU_POURCENTAGE=$(bc<<<"$(tr -d '.'<<<$TEMPS)/$TOTALS")
      
      grep IMAGE /tmp/affichetout.txt && echo "#ENTRE : $MEDIA\nSORTIE : $NOM.$EXTENTION"
      
      echo $ACTU_POURCENTAGE
      }
      
      DECOMPTE=$(ffmpeg -i "$1" 2>&1 | grep Duration  | awk '{ print $2 }' | tr ':.,' ' ')
      DECOMPTEH=$(cut -d' ' -f1<<<$DECOMPTE)
      DECOMPTEM=$(cut -d' ' -f2<<<$DECOMPTE)
      DECOMPTES=$(cut -d' ' -f3<<<$DECOMPTE)
      TOTALS=$(bc<<<"$DECOMPTES+$DECOMPTEM*60+$DECOMPTEH*3600")
      
      ffmpeg -i "$1" $COMMANDE "$NOM.$EXTENTION" 2> /tmp/Video2flv.log &
      PID=$!
      
      while [[ $(pidof ffmpeg)  = $PID ]]
      do
      	sleep .2
      	POURCENTAGE
      done | zenity --progress  --auto-close --title=Video2flv
      
      [[ $(tail -n 1 /tmp/Video2flv.log | grep overhead ) ]] && zenity --info --title=Video2flv --text="Encodage terminé !" || VIDEO2FLV_ERROR 
      
      exit 0

      Maintenant …

      wait "$PID"

      …va attendre la fin du process pour me donner l’état de sortie c’est sur , mais je le place où ?
      Car en fait ffmpeg est détaché , j’ai son PID mais le plus important pour moi est la fonction POURCENTAGE qui me permet une progress bar
      Maintenant si je ferme la progress bar avant la fin de l’execution de ffmpeg je dois tuer ffmpeg et indiquer a l’utilisateur que l’encodage ne c’est pas terminé correctement !
      Si ffmpeg plante pour une raison ou une autre je doit arreter la progress bar et indiquer a l’utilisateur que l’encodage ne c’est pas terminé correctement !
      Si l’encodage c’est bien derouler je dois indique que tout c est bien passe

      Le bout de code :

      strace -p "$PID" -e trace=process -o  /tmp/traceff.log

      Me donne l’etat de sortie dans le fichier /tmp/traceff.log que je n’ai plus qu’a analyser , wait me semble une bonne solution mais je sais pas où ni comment l’employer


      Oh on donc ce que tu veux savoir dans un premier temps c’est s’il tourne encore, pas récupérer son code de retour. Donc dans ta boucle tu peux faire un test à base de ps (ou même de ls /proc/$PID) pour savoir si ton processus tourne encore et faire un break s’il ne tourne plus.

      Puis a la fin une fois qu’il est mort tu peux quand même récupérer son code de retour avec wait.


      Si tu regarde mon faut script , la boucle qui créé la progress bar de zenity est conditionnée par le PID de ffmpeg :
      -si il est présent cela continu jusqu’au 100 % de la progress
      -si il n’est plus présent cela stop la progress

      Ce que je cherchais et que j ‘ai trouvé c’est comment connaitre l’etat de sortie de ffmpeg : la bar peut monter a 99 et ffmpeg planté !? J’ai modifié mon script ( vraiment laid ) et vais le simplifier .

      Mais avec wait je ne vois toujours pas comment faire ?? hmm

      La solution que j’ai trouvé :

      function VIDEO2FLV_ERROR()
      {
          kill $PID
          zenity --error --title=Video2flv --timeout=1
          zenity --text-info --filename=/tmp/Video2flv.log --title=Video2flv  --width=800 --height=600
          exit 1
      }
      
      function POURCENTAGE()
      {
          sed -e 's/\r/\n/g' /tmp/Video2flv.log | grep time= | tail -n 1 | sed -e 's/frame/IMAGE/;s/fps/\nFPS/;s/q/\nQUALITEE/;s/size/\nPOID/;s/time/\nTEMPS/;s/bitrate/\nBITRATE/' | tr -d ' ' > /tmp/affichetout.txt
      
          . /tmp/affichetout.txt
      
          ACTU_POURCENTAGE=$(bc<<<"$(tr -d '.'<<<$TEMPS)/$TOTALS")
      
          grep IMAGE /tmp/affichetout.txt && echo "#ENTRE : $MEDIA\nSORTIE : $NOM.$EXTENTION"
      
          echo $ACTU_POURCENTAGE
      }
      
      DECOMPTE=$(ffmpeg -i "$1" 2>&1 | grep Duration  | awk '{ print $2 }' | tr ':.,' ' ')
      DECOMPTEH=$(cut -d' ' -f1<<<$DECOMPTE)
      DECOMPTEM=$(cut -d' ' -f2<<<$DECOMPTE)
      DECOMPTES=$(cut -d' ' -f3<<<$DECOMPTE)
      TOTALS=$(bc<<<"$DECOMPTES+$DECOMPTEM*60+$DECOMPTEH*3600")
      
      ffmpeg -i "$1" $COMMANDE "$NOM.$EXTENTION" 2> /tmp/Video2flv.log &
      PID=$!
      
      strace -p "$PID" -e trace=process -o  /tmp/traceff.log &
      
      while [[ $(pidof ffmpeg)  = $PID ]]
      do
          sleep .2
          POURCENTAGE
      done | zenity --progress  --auto-close --title=Video2flv
      
      [[ "$(tail -n 1 /tmp/traceff.log | sed -e 's/exit_group//' | tr -d ' =?)(' )" = 0 ) ]] && zenity --info --title=Video2flv --text="Encodage terminé !" || VIDEO2FLV_ERROR 
      
      exit 0

      Et la que ffmpeg plante ou non , que je le kill , que j’arrete la progress ou pas j’obtient bien l’état de sortie de ffmpeg cool

      Merci !!


      Je ne vois pas ce qu’apporte ta commande complete sachant que de la sortie de strace tu n’extraie que le code de retour.

      Un truc type
      wait $PID
      echo $?
      à la place de ton avant dernière ligne donnerait la même chose.


      strace me renvoi 0 si ffmpeg a abouti !
      wait va attendre la fin du process pour la même chose , c’est vrai , mais je le place ou ??
      Si je met :

      while [[ $(pidof ffmpeg)  = $PID ]]
      do
          sleep .2
          POURCENTAGE
      done | zenity --progress  --auto-close --title=Video2flv
      
      wait $PID
      SORTIE=$?
      
      [[ "$SORTIE" = 0 ) ]] && zenity --info --title=Video2flv --text="Encodage terminé !" || VIDEO2FLV_ERROR 
      
      exit 0

      Ca ne marche pas car en fermant la progress de zenity , wait attend la fin de ffmpeg alors que je veux que si on ferme la progress on stoppe ffmpeg , c’est pour cela que oui je voudrais utiliser simplement wait mais ou et comment l’utiliser ??


      Dans ton cas actuel tu ne stoppe pas ffmpeg non plus, tu ne fais que le laisser tourner en arrière plan.

      Pour stopper ffmpeg il faut faire un kill sur son pid.
      Tu peux détecter que zenity a été fermé de 2 façons, soit le pid de ffmpeg existe toujours, soit a partir du code de retour de zenity.


      Regarde la boucle while elle conditionne la progress de zenity par le pid de ffmpeg

      Je pourrais egalement recuperer la sortie de zenity pour savoir si le progress a été fermé ou si il a été au bout MAIS
      Si je tue ffmpeg avec un gros killall ffmpeg , la boucle while s’arrete et la progress aboutie tout de même a cause de l’auto-close donc je ne peux pas savoir si ffmpeg a planter en regardant la sortie de zenity !!
      D’ou mon soucis sad


      Pour le boucle while je ne vois pas la différence avec ou sans strace.

      Si ffmpeg s’est bien terminé wait retournera 0 et s’il a été tué il retournera une valeur différente.


      Exactement !

      Seulement à cause de l’auto-close si ffmpeg est tué ma boucle s’arrete et zenity stoppe sur une reussite donc je ne peux me fier a la sortie de zenity !
      Si mon wait est apres zenity même si je ferme zenity il attendra la fin de ffmpeg alors que souhaite le tuer!
      Vois tu pourquoi je ne sais où le placer ??
      Le top serait de tout placer dans une fonction "piper" dans zenity et la un --auto-kill en plus de --auto-close et encore si la boucle while s’arrette zenity l’interprete comme la fin normal du processus parent donc je n’obtiendrais de toute façon pas ce que je souhaite sad puisque je veux avant tout savoir si ffmpeg a planté ou pas !!
      Bon je suis demi-noob/semi-geek et autodidacte , ceci explique certainement cela …:rolleyes:


      Si ton ffmpeg est encore lancé après la fin de zenity c’est que zenity s’est arreté en premier, tu peux donc tuer ffmpeg. Tu placera ton wait après, ou à la place du kill (if then else).


      Totor : Bonjour


      Totor :Bonjour Totor

      J’ai trouvé ton topic il y à un moment mais ne maitrisant pas awk j’ai préféré essayé par moi même de creer une barre de progression !
      C’est plus un exercice qu’autre chose car a vrai dire en ligne de commande çà passe tous seul .

      Maitenant j’essais avant tout d’etre capable de suivre un process et ffmpeg m’arrange bien , ce logiciel sera surtout utile pour ma femme .

      J’ai remarqué que pour un traitement par lot ta fonction se compliquait également et qu’il devien difficile de contrôler efficacement ffmpeg et d’en tirer les infos pour la progress !
      Mais ca fait plaisir de voir que dès qu’un probleme en bash apparait , les Maîtres également wink
      Peck:
      C’est vrai que je peux kill ffmpeg apres zenity mais du coup c’est systématique et wait devient inutile !
      Je vais faire une tiote fonction genre :

      ffmpeg -i $TRUC $MACHIN &
      PID=$!
      wait $PID
      return $?

      J’ai la progress pour le traitement par lot mais du coup les PID de ffmpeg seront different c’est entre autre pour cela que je souhaite utiliser wait qui me parait le mieux a meme de m’aider !
      Merci pour ta soluce je vais l’adapter et  tester de suite …

      Dernière modification par Yannou90 (Le 09/08/2010, à 09:52)


      Et bien merci Peck , c’est vrais que c’était tout bête , voilà coment j’ai fais :

      function ENCODE()
      {
      	ffmpeg -i "$1" $COMMANDE "$NOM.$EXTENTION" 2> /tmp/Video2flv.log &
      	wait $!
      	RETOUR=$?
      	[[ "$RETOUR" != 0 ]] && VIDEO2FLV_ERROR
      	zenity --info --title=Video2flv --text="Encodage terminé !"
      	exit "$RETOUR"
      }
      
      ENCODE "$1" &
      
      while [[ $(pidof ffmpeg) ]]
      do
      	sleep .2
      	POURCENTAGE
      done | zenity --progress  --auto-close --title=Video2flv
      
      [[ "${PIPESTATUS[0]}" != "0" ]] && kill  $(pidof ffmpeg)
      
      exit 0

      Et çà marche nickel !! big_smile
      C’était pourtant pas compliqué roll


      Et du coup tu ne te sers jamais du code de retour de ffmpeg. Pourtant, ca pourrait être utile pour générer toi même un code de retour (sinon le exit 0 ne sert à rien) ce qui rendra ton script lui-même utilisable par d’autres scripts.


      Si il m’est utile : exit $RETOUR :

      function ENCODE()
      {
          ffmpeg -i "$1" $COMMANDE "$NOM.$EXTENTION" 2> /tmp/Video2flv.log &
          wait $!
          RETOUR=$?
          [[ "$RETOUR" != 0 ]] && VIDEO2FLV_ERROR
          zenity --info --title=Video2flv --text="Encodage terminé !"
          exit "$RETOUR"
      }

      Mais ce script  est censé être utilisé en graphique pas en terminal , c’est pour ma chérie cool
      Apres pour ce servir de ce script pour un autre pour le moment il n’y a pas d’interet je suis toujours en teste et souhaite traiter de multiple fichier donc c’est une "alpha" si on peut dire .
      Mais merci de ton intéret wink

      Dernière modification par Yannou90 (Le 09/08/2010, à 12:18)


      Peck a écrit :

      Et du coup tu ne te sers jamais du code de retour de ffmpeg. Pourtant, ca pourrait être utile pour générer toi même un code de retour (sinon le exit 0 ne sert à rien) ce qui rendra ton script lui-même utilisable par d’autres scripts.

      ce n’est pas exacte. S’il n’y avait pas de "exit 0″, le code retour serait celui de la dernière instruction exécutée. A savoir : [[ "${PIPESTATUS[0]}" != "0″ ]] && kill  $(pidof ffmpeg)


      Bon un peu plus serieusement pour la sortie d’etat du script :

      function ENCODE()
      {
      	ffmpeg -i "$1" $COMMANDE "$NOM.$EXTENTION" 2> /tmp/Video2flv.log &
      	wait $!
      	return $?
      }
      
      ENCODE "$1" &
      PID=$!
      
      sleep .2
      
      while [[ $(pidof ffmpeg) ]]
      do
      	sleep .2
      	POURCENTAGE
      done | zenity --progress  --auto-close --title=Video2flv
      
      if [[ "${PIPESTATUS[0]}" != "0" ]]
      then
      	kill  $(pidof ffmpeg)
      fi
      
      wait $PID
      SORTIE=$?
      
      if [[ "$SORTIE" = "0" ]]
      then
      	zenity --info --title=Video2flv --text="Encodage terminé !"
      else
      	zenity --error --title=Video2flv --timeout=1
      	zenity --text-info --filename=/tmp/Video2flv.log --title=Video2flv  --width=800 --height=600
      fi
      
      exit $SORTIE

      Ainsi mes doléances sont réspectées , j’ai l’état de sortie de ffmpeg qui devient celle de mon script , le sujet et donc réellement RESOLU , merci PECK et TOTOR


      bonjour,
      ce fil m’a fait avancer à pas de géant sur mon script donc je renvoie l’ascenseur
      voici un "pré" script fonctionnel dans lequel il faut juste modifier les valeurs de
      SOURCE, DESTINATION, et éventuellement RESOLUTION
      les (gros) plus apportés par ce fil :
      zenity --progress avec infos parsées et affichées ainsi que le % d’avancement :
      possibilité d’arrêter ffmpeg proprement pendant le déroulement du script ; ce qui renvoie le log

      #!/bin/bash
      # ----------------------------------------------
      nomlogiciel="${0##*/}"
      FONCTION="script de démo pour l'utililsation de ffmpeg pour la transformation d'une vidéo mp4 en gif
      avec un zenity progress et gestion des arrêts"
      VERSION="alpha"
      # NOTES DE VERSIONS
      # ----------------------------------------------
      # https://forum.ubuntu-fr.org/viewtopic.php?id=2011864
      # https://forum.ubuntu-fr.org/viewtopic.php?id=411097
      #
      # ----------------------------------------------
      echo "lancement $nomlogiciel..." ;
      
      function journal () {
      	echo -e "${@}" # >/dev/null
      }
      
      txtTITLE="Conversion Video"
      
      SOURCE="/home/utilisateur/Vidéos/uneVideo.mp4"
      DESTINATION="/home/utilisateur/Images/uneSortie.gif"
      RESOLUTION="320x180"
      TMP_LOG="/tmp/Video2flv.log"
      TMP_TOUT="/tmp/affichetout.txt"
      
      echo "
      SOURCE = $SOURCE
      DESTINATION = $DESTINATION
      RESOLUTION = $RESOLUTION
      "
      
      function VIDEO2FLV_ERROR () {
      # inutile
      	kill $PID
      	zenity --error --title="${txtTITLE}" --timeout=1
      	zenity --text-info --filename="${TMP_LOG}" --title="${txtTITLE}" --width=800 --height=600
      	exit 1
      }
      function POURCENTAGE () {
      	sed -e 's/\r/\n/g' "${TMP_LOG}" | \
      	grep time= | \
      	tail -n 1 | \
      	sed -e 's/frame/IMAGE/;s/fps/\nFPS/;s/q/\nQUALITEE/;s/size/\nPOID/;s/time/\nTEMPS/;s/bitrate/\nBITRATE/;s/speed/\nSPEED/' | \
      	tr -d ' ' > "${TMP_TOUT}"
      
      	. "${TMP_TOUT}"
      
      	IFS=':' leTemps=( $TEMPS )
      	ACTU_POURCENTAGE=$(bc<<<"(${leTemps[2]}+${leTemps[1]}*60+${leTemps[0]}*3600)*100/$TOTALS")
      
      	grep IMAGE "${TMP_TOUT}" && \
      	echo "#ENTRE : $SOURCE\nSORTIE : $DESTINATION" || \
      	echo "#ENTRE : $SOURCE\nSORTIE : $DESYINATION"
      
      	echo ${ACTU_POURCENTAGE}
      }
      function ENCODE () {
      	# ffmpeg -i "$1" $COMMANDE "$NOM.$EXTENTION" 2> /tmp/Video2flv.log &
      	ffmpeg -y -i "${SOURCE}" -s "${RESOLUTION}" "${DESTINATION}" 2> "${TMP_LOG}" &
      	wait $!
      	return $?
      }
      function Mp42Gifclassique () {
      	journal "**********************
      	Mp42Gifclassique
      Création d’un GIF animé, méthode «classique»
      A) gif contenant toute la vidéo
      ffmpeg -y -i ${SOURCE} -s ${RESOLUTION} ${DESTINATION}"
      # ffmpeg -y -i "${SOURCE}" -s "${RESOLUTION}" "${DESTINATION}"
      
      DECOMPTE=$(ffmpeg -i "$SOURCE" 2>&1 | grep Duration | awk '{ print $DESTINATION }' | tr ':.,' ' ')
      DECOMPTEH=$(cut -d' ' -f2<<<$DECOMPTE)
      DECOMPTEM=$(cut -d' ' -f3<<<$DECOMPTE)
      DECOMPTES=$(cut -d' ' -f4<<<$DECOMPTE)
      TOTALS=$(bc<<<"$DECOMPTES+$DECOMPTEM*60+$DECOMPTEH*3600")
      
      # echo "DECOMPTE=$DECOMPTE"
      # echo "DECOMPTEH=$DECOMPTEH"
      # echo "DECOMPTEM=$DECOMPTEM"
      # echo "TOTALS=$TOTALS"
      
      ENCODE &
      PID=$!
      
      sleep .5
      
      while [[ $(pidof ffmpeg) ]]
      do
      	sleep .2
      	POURCENTAGE
      done | zenity --progress --auto-close --title="${txtTITLE}"
      
      if [[ "${PIPESTATUS[0]}" != "0" ]]
      then
      	kill $(pidof ffmpeg)
      fi
      
      wait $PID
      SORTIE=$?
      
      if [[ "$SORTIE" = "0" ]]
      then
      	zenity --info --title="${txtTITLE}" --text="Encodage terminé !"
      else
      	zenity --error --title="${txtTITLE}" --text="Encodage arrêté par l'utilisateur !" --timeout=2
      	zenity --text-info --filename="${TMP_LOG}" --title="${txtTITLE}" --width=800 --height=600
      fi
      
      # exit $SORTIE
      
      	journal "fin Mp42Gifclassique"
      }
      Mp42Gifclassique
      
      echo fin
      
      exit 0

 

Aucun commentaire

 

Laissez un commentaire