Forum Programmation.shell Petits problèmes pour un script

Posté par .
Étiquettes : aucune
0
23
fév.
2011

Bonjour,

Je me suis fait un petit script pour créer des images HDR sous Gimp. Basiquement, on lui donne des images raw, et il se charge de les convertir en tif, de les aligner et de créer une pile de calques dans un fichier psd. Le résultat est ensuite ouvert dans Gimp.

J'ai quelques problèmes encore que je n'arrive pas à régler...

1/ Je ne vois pas comment gérer les espaces dans les noms de fichier. J'ai crée un fichier .desktop pour ouvrir graphiquement les images depuis un explorateur (avec %f comme expliqué là-bas). mais comment discriminer un espace qui sépare deux fichiers d'un espace qui est dans un nom de fichier ?

2/ A la fin du script, je lance Gimp, mais celui-ci se ferme si on ferme le terminal dans lequel s'éxécute le script... j'ai essayé avec '&', nohup, etc. mais je sèche là

Comme les experts semblent courir les rues ici, je tente ma chance, je copie/colle le script en dessous :)

#!/bin/bash
[snip]
# Default values
TMPDIR=/tmp # without ending slash
PRGM=gimp # External editor (must be able to open psd files)
ALIGN=1
BATCH=2 # 1: all images processed interactively, 2: first image only, 3: batch mode
HELP=0
KEEPTMP=0
OUTDIR=$TMPDIR # Output directory and tmp directory are the same by default
while getopts p:ni:d:hto: option
do
 case $option in
 p)
 PRGM=$OPTARG ;;
[moultes options]
 o)
 OUTDIR=$OPTARG ;;
 esac
done
shift $(($OPTIND -1)); 
IMAGES=$*
WRKDIR="$TMPDIR/HDRstack"
if [ "$HELP" = 1 ]; then
echo " Usage : HDRstack [options] <raw image files>"
 [snip]
 echo "	-o : Set folder for output file"
else
 # Display some infos at start
 echo ""
[snip]
 echo ""
 
 # Clean up 
 if test -d "$WRKDIR"; then
echo "Cleaning temporary folder"
 rm $WRKDIR/* 
 else
echo "Creating temporary folder"
 mkdir $WRKDIR
 fi
# Image conversion
 echo ""
 # All images interactively processed
 if [ "$BATCH" = 1 ]; then
echo "Converting images (interactive image processing)"
 for img in $IMAGES; do # Converts raw images
 echo " Processing $(basename $img)..."
 ufraw $img --out-path="$WRKDIR" --out-type=tif &> /dev/null
 done
 # First image only
 elif [ "$BATCH" = 2 ]; then
echo "Converting images (interactive processing for first image)"
 FIRST=$(echo $IMAGES|cut -d " " -f 1) # Get first image filename
 IMAGES=$(echo $IMAGES|cut -d " " -f 2-) # Remove first image from list
 #Process first image
 echo " Processing $( basename $FIRST )..."
 ufraw "$FIRST" --out-path="$WRKDIR" --out-type=tif &> /dev/null
 # Batch process the rest
 for img in $IMAGES; do
echo " Processing $( basename $img )..."
 ufraw-batch $img --out-path=$WRKDIR --out-type=tif &> /dev/null
 done
 # Batch mode only
 else 
echo "Converting images (batch processing)"
 for img in $IMAGES; do
echo " Processing $(basename $img)..."
 ufraw-batch $img --exposure=0 --out-path=$WRKDIR --out-type=tif &> /dev/null
 done
 fi
 
# Image alignment
 if [ "$ALIGN" = 1 ]; then
echo ""
 echo "Building image stack"
 echo " Aligning images..."
 align_image_stack -p $WRKDIR/output.pto -a $WRKDIR/aligned_ $WRKDIR/*.tif &> /dev/null
 
 echo " Creating output file..."
 PTtiff2psd -s -o $TMPDIR/output.psd $WRKDIR/aligned_* &> /dev/null
 else # Alignment turned off
 echo "Creating output file..."
 PTtiff2psd -s -o $OUTDIR/output.psd $WRKDIR/aligned_*.tif &> /dev/null
 fi
# Temp files clean up
 if [ $KEEPTMP = 0]; then
echo ""
 echo "Cleaning up tmp folder"
 rm -r $WRKDIR
 fi
echo ""
 echo "Done !"
 echo ""
 echo "Opening result"
 $PRGM $OUTDIR/output.psd 
fi

Toute remarque est aussi la bienvenue :) Merci ! (et j'ai fait de mon mieux pour l'anglais /o)

  • # Pour le point 2

    Posté par (site web personnel) . Évalué à 1.

    Une solution ( bash ) :

    $ ( command & )

    Tu peux ensuite fermer le terminal et ton appli continue de s'exécuter.

    Source :
    http://www.commandlinefu.com/commands/view/7653/a-child-process-which-survives-the-parents-death-zsh-version

    • [^] # Re: Pour le point 2

      Posté par . Évalué à 0.

      Bah justement, ça marche tout à fait quand j'appelle le programme depuis un terminal.

      J'ai crée un fichier .desktop (cf ci-dessous). Quand je le lance graphiquement depuis un navigateur de fichiers, un terminal s'ouvre et quand ce terminal se ferme, gimp s'arrête, même avec ( gimp output.psd )...

      Peut-être que finalement l'option Terminal=true est prévue pour terminer tout programme quand le terminal se ferme...

      [Desktop Entry]
      Name=HDRstack
      GenericName=Create an image stack
      GenericName[fr]=Aligne et créé une pile d'image
      Comment=Create an image stack
      Comment[fr]=Aligne et crée une pile d'image
      Encoding=UTF-8
      Version=1.0
      Type=Application
      Categories=Graphics;Photography;
      Exec=HDRstack %F
      Terminal=true
      StartupNotify=true
      MimeType=application/x-ufraw;image/x-dcraw
      Icon=gimp.png
      • [^] # Re: Pour le point 2

        Posté par . Évalué à 0.

        Je me réponds à moi-même : ça a marché en mettant des guillemets aux endroits qui vont bien...

        Merci, c'est tout bon !

  • # Il me reste le point 2

    Posté par . Évalué à 1.

    Je ne vois pas comment gérer les espaces dans les noms de fichier

     IMAGES="$@" au lieu de IMAGES=$*
    
    • [^] # Re: Il me reste le point 2

      Posté par . Évalué à 1.

      Je voulais dire le 1er point. Je suis très perturbé par cette syntaxe markdown.

      • [^] # Re: Il me reste le point 2

        Posté par . Évalué à 0.

        Bah justement j'ai beau essayer, ça ne sépare pas les espaces, il y a sûrement quelque chose qui m'échappe...

        Exemple : avec le bout de code suivant, qui reproduit mon problème finalement :

        [snip]
        shift $(($OPTIND -1)); 
        IMAGES="$@"
        for i in $IMAGES; do
        echo $i
        done

        Ça me donne ça par exemple :

        $ ./test IMGP6266.DNG I\ MGP6265.DNG
        IMGP6266.DNG
        I
        MGP6265.DNG

        D'où blocage...

        • [^] # Re: Il me reste le point 2

          Posté par . Évalué à 2.

          Alors c'est peut être que getopt met la zone, ou alors autre chose. Pour t'en convaincre, essaye la chose suivante:

          > cat foo
          #!/bin/sh
          for arg in $*; do echo "$arg"; done
          for arg in "$@"; do echo "$arg"; done
          > ./foo a b\ c
          a
          b
          c
          a
          b c
          

          donc dans le 1er cas ($*), les arguments avec espaces ne sont pas préservés, alors qu'ils le sont dans le 2nd cas. Après, je n'utilise jamais getopt, laors je ne peux pas te dire. À toi de creuser de ce côté là.

          De mon côté je fais plutôt des choses du genre (avec case, parce que case ça autorise le pattern matching et que je n'aime pas les if parce que j'oublie toujours la syntaxe et en plus ça fork, contrairement à if [ [ mon-test ]] mais qui n'existe qu'en bash je crois ):

          for arg
          do
           case "$arg" in
           -a) a_opt=1; shift;;
           --truc) truc_opt=2ドル; shift; shift;;
           *) break,
           esac
          done
          # etc.
          

          Note pour les spéciliste du markdown: comment fait on pour avoir 2 crochets ouvrants à suivre sans qu'il me mettre un lien vers 1 truc wikipedia qui n'existe pas ? Grrrr, ça devient compliquer d'aider :(

          • [^] # Re: Il me reste le point 2

            Posté par . Évalué à 0.

            J'ai trouvé \o/

            Pour des raisons que je m'explique pas trop, c'est la ligne IMAGES="$@" qui fout le boxon. Exemple :

            % cat test
            #!/bin/bash
            for arg in "$@"; do echo "$arg"; done
            IMAGES="$@"
            for arg in "$IMAGES"; do echo "$arg"; done
            % ./test pl\ ip plap plop
            pl ip
            plap
            plop
            pl ip plap plop

            J'ai remplacé les variables dans le script, maintenant ça marche, merci ! (au prix d'être un poil moins lisible mais bon j'en suis pas là)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.