1

I made a simple bash shell script to perform three imagemagick commands on every file in a directory. I did not use & nor | to make each command run concurrently.

#!/bin/bash


jpg="$1/*.jpg"
jpeg="$1/*.jpeg"
JPG="$1/*.JPG"
png="$1/*.png"
#convert to png
to_png() {
    for file in $jpg; do mogrify -format png $file; rm $file; done
    for file in $jpeg; do mogrify -format png $file; rm $file; done
    for file in $JPG; do mogrify -format png $file; rm $file; done
}

#format for 4k
to_4k() {
    for file in $png; do convert $file -resize 3840x2160 $file; done
}

#put on transparent background
to_trans() {
    for file in $png; do composite -gravity center $file -geometry 3840x2160 /path/to/transparent/background $file; done
}

do_stuff() {

    to_png
    to_4k
    to_trans

}

if [ -d "$1" ];
then do_stuff
else echo "You didn't enter a directory. Please try again."
fi

When there are any .jpg files in the directory I get error messages. Is ImageMagick telling bash that the command is completed before the file is finished?

convert: Expected 8 bytes; found 0 bytes `/path/to/picture/image.png' @ warning/png.c/MagickPNGWarningHandler/1669.
convert: Read Exception `/path/to/picture/image.png' @ error/png.c/MagickPNGErrorHandler/1643.
convert: corrupt image `/path/to/picture/image.png' @ error/png.c/ReadPNGImage/3973.
convert: no images defined `/path/to/picture/image.png' @ error/convert.c/ConvertImageCommand/3210.
composite: Expected 8 bytes; found 0 bytes `/path/to/picture/image.png' @ warning/png.c/MagickPNGWarningHandler/1669.

Using sleep for a long duration between commands resolves this issue, but it's pretty sloppy.

side note: I stored directories in variables because using $1/*.jpg within a for loop fails to expand $1 and * apparently. Bash returns an error saying that /path/to/*.jpg doesn't exist.

I'm using Ubuntu 16.04 (x86_64), GNU bash 4.3.48, and ImageMagick 6.8.9-9

  • 1
    you need to do ... mogrify -format "$1/${file%.*}.png" "$file"; ..., next quote all your variables – αғsнιη Dec 14 '17 at 6:50
  • I'm curious too, run bash +x to see step by step execution, I'm running my own lab here – BrenoZan Dec 14 '17 at 17:21
2

$1 inside function is not the same as $1 outside function.

so you need to do save it at script begin: dir="$1", ...and use $dir everywhere else.

this way you will solve first strange thing you noticed yourself (bash: path doesn't exist)... but it will probably solve everything else.

Your way of resolving was not complete you must put vars in quotes, but then globe expanding will be wrong ... and the only thing you can do is to clean up your code because simplified version of your script works well for sure:

#!/bin/bash

shopt -s nullglob ; set -o xtrace           #xtrace for debug
dir="$1" ; [ -d "$dir" ] || dir=.
for file in "$dir"/*.{jpg,jpeg,JPG}; do mogrify -format png "$file"; rm "$file"; done
for file in "$dir"/*.png; do convert "$file" -resize 3840x2160 "$file"; done
for file in "$dir"/*.png; do composite -gravity center "$file" -geometry 3840x2160 /home/d/bin/youtube_tools/4kclear.png "$file"; done
  • Turns out that it does work with $1 inside the for loop. Your other points really helped out. Thanks. – soundssilver Dec 14 '17 at 23:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.