1

I try to improve with semaphores some photo processing script I use. I run sable GNU/DEBIAN There is a function called travail that uses a given filename as an argument, and that processes the file.

For now, that function is called in the same script with a loop :

  for i in *.png ; do
    travail $i &
    done

The problem is that it uses a lot of memory if there are a lot of pictures. I would like to use semaphores to limit the number of threads.

I tried:

for i in *.png ; do
sem -j+0 travail $i
done
sem --wait

But it does not work, with the following message : /bin/bash: travail : commande introuvable (that means command not found)

I try to add export -f travail after the function has been defined, but it does not work.

Exemple of the output (2 files for this exemple)

travail sur image 113_XT1S3739.png convert-im6.q16: unable to open image x': Aucun fichier ou dossier de ce type @ error/blob.c/OpenBlob/2874. convert-im6.q16: no decode delegate for this image format' @ error/constitute.c/ReadImage/560. convert-im6.q16: invalid argument for option -quality': -unsharp @ error/convert.c/ConvertImageCommand/2460. composite-im6.q16: invalid argument for option-quality': sortie/grand_format/ne_pas_publier_113_XT1S3739.jpg @ error/composite.c/CompositeImageCommand/1241. travail sur image 113_XT1S3779.png convert-im6.q16: unable to open image x': Aucun fichier ou dossier de ce type @ error/blob.c/OpenBlob/2874. convert-im6.q16: no decode delegate for this image format' @ error/constitute.c/ReadImage/560. convert-im6.q16: invalid argument for option -quality': -unsharp @ error/convert.c/ConvertImageCommand/2460. composite-im6.q16: invalid argument for option-quality': sortie/grand_format/ne_pas_publier_113_XT1S3779.jpg @ error/composite.c/CompositeImageCommand/1241. etc.

For more information, Here is the script

   # !/bin/bash
    # _____________________________ Paramètres
    T_WEB="1000"   # Taille maxi des images pour le web
    Q_WEB="100"   # Qualité des images pour le web (100 car il faut les réouvrir pour mettre le logo)
    #
    H_MOY="1795"   # Hauteur maxi des images pour impression ?x15
    L_MOY_11="1347"  # Largeur maxi des images pour impression 11x15
    L_MOY_10="1204"  # Largeur maxi des images pour impression 10x15
    Q_MOY="96"   # Qualité des images pour impression 10x15
    #
    Q_GRA="99"   # Qualité des grandes images
    #
    B_INT="0.1%"   # Taille de la bordure intérieure
    B_CEN="0.3%"   # Taille de la bordure intérieure
    B_EXT="4%"   # Taille de la bordure extérieure
    C_INT="white"   # Couleur de la bordure intérieure
    C_CEN="black"   # Couleur de la bordure intérieure
    C_EXT="white"   # Couleur de la bordure extérieure
    #
    # __________________________________________________________________
    #
    # Fonction principale
    #
    function travail
    {
    # Lecture du nom de fichier à traiter
    local f=$1
    echo 'travail sur image' $f
    # Récupération d'infos sur l'image en cours
    local LARG=`convert -quiet -ping $f -format "%w" info:`
    local HAUT=`convert -quiet -ping $f -format "%h" info:`
    local LARG=${LARG:0:4} # On ne conserve que les 4 premiers chiffres, le reste n'est pas bon
    local HAUT=${HAUT:0:4}
    local DECALE_X=$(($LARG/24))
    local DECALE_Y=$(($HAUT/22))
    #
    # Récupération du nom du fichier et de l'extension
    local nomfichier="${f%%.*}"
    #
    # Recuperation donnees EXIF (elles sont écrites dans un fichier temporaire)
    if [ -f "${nomfichier}.RAF" ]
    then
     exiv2 -q ex ${nomfichier}.RAF
    fi
    if [ -f "${nomfichier}.NEF" ]
    then
     exiv2 -q ex ${nomfichier}.NEF
    fi
    #
    # Ajout des bordures
    convert $f -quiet -bordercolor ${C_INT} -border ${B_INT}  -bordercolor ${C_CEN} -border ${B_CEN} -bordercolor ${C_EXT} -border ${B_EXT}x${B_EXT} -quality 01 /tmp/$f
    #
    # Création image WEB
    convert /tmp/$f -resize ${T_WEB}x${T_WEB} -quality ${Q_WEB} -unsharp 3 sortie/web/${nomfichier}_pour_internet.jpg
    if [ -f "${nomfichier}.NEF" ]
    then
     mv ${nomfichier}.exv sortie/web/${nomfichier}_pour_internet.exv
     exiv2 in sortie/web/${nomfichier}_pour_internet.jpg
     exiftool -Orientation=1 -n sortie/web/${nomfichier}_pour_internet.jpg
     rm sortie/web/${nomfichier}_pour_internet.jpg_original
    fi
    #
    # Ajout logo puis conversion en JPG
    composite -compose Over -geometry +$DECALE_X+$DECALE_Y -gravity SouthEast /home/pierre/Documents/Photo/baniere-logo/logo_800x600.png /tmp/$f -quality ${Q_GRA} sortie/grand_format/ne_pas_publier_${nomfichier}.jpg
    #
    if [ -f "${nomfichier}.NEF" ]
    then
     mv sortie/web/${nomfichier}_pour_internet.exv sortie/grand_format/ne_pas_publier_${nomfichier}.exv
     exiv2 in sortie/grand_format/ne_pas_publier_${nomfichier}.jpg
     exiftool -Orientation=1 -n sortie/grand_format/ne_pas_publier_${nomfichier}.jpg
     rm sortie/grand_format/ne_pas_publier_${nomfichier}.jpg_original
     rm sortie/grand_format/ne_pas_publier_${nomfichier}.exv
    fi
    # Suppression des fichiers inutiles
    rm /tmp/$f
    if [ -f "${nomfichier}.RAF" ]
    then
     rm ${nomfichier}.exv
    fi
    }
    #
    # _____________________________ Création des dossiers et préparation ___________________________________________
    if test -e sortie; then
    rm -rf sortie
    fi
    mkdir sortie
    mkdir sortie/web
    mkdir sortie/grand_format
    #
    # _____________________________ Appel de la fonction en parallèle sur toutes les images PNG
    #
    #
    for i in *.png ; do
             travail $i &                                                                 
    done 
    wait
    #
    # _____________________________ Fin de la fonction ________________________________________________________
    #
    echo
    echo TERMINÉ
9
  • 1
    sem can only execute external programs, not shell functions (or aliases). rewrite your travail function as a shell script and make it executable. run sem -j+0 /path/to/travail.sh Commented Aug 29, 2019 at 16:14
  • it might be worth defining travail in your .bashrc or .bash_profile (i don't know if it sources either or both of them or not). but there's little or no benefit over just putting it in standalone sccript. Commented Aug 29, 2019 at 16:18
  • I would prefer having a single script file than using a travail script and another script to prepare the directories and call it. Is it a way to parallelise a function ? Commented Aug 29, 2019 at 16:23
  • another thing to try: sem -j+0 bash -c "travail $i" (this, if it works, would require travail to be exported, or defined in .bashrc). Commented Aug 29, 2019 at 16:26
  • See also unix.stackexchange.com/q/235155/117549 Commented Aug 29, 2019 at 16:31

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.