LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Order of "attack" in BASH scripts? (https://www.linuxquestions.org/questions/programming-9/order-of-attack-in-bash-scripts-887512/)

SilversleevesX 06-21-2011 06:11 AM

Order of "attack" in BASH scripts?
 
Let me explain what I mean with this example.

I have a script that is the "slimming down and joining" of two other scripts written to perform very similar tasks on JPEG files. One of the scripts read in filenames from a text file and annotated, while the other trimmed four-letter "hint" substrings from the file names. Here's the code of the amalgamated script:
Code:

#!/bin/bash
exec 5<fields.txt
while IFS="," read -u5 FILE CATE CRED SOUR WRIT TRANS FIXID OBJNM LOCN
do
        fname=`basename "$FILE"`
        echo -e "Working on item $fname now."
                exiv2 -kM"set Iptc.Application2.Category String $CATE" $FILE
                exiv2 -kM"set Iptc.Application2.Credit String $CRED" $FILE
                exiv2 -kM"set Iptc.Application2.Source String $SOUR" $FILE
                exiv2 -kM"set Iptc.Application2.Writer String $WRIT" $FILE
                exiv2 -kM"set Iptc.Application2.TransmissionReference String $TRANS" $FILE
                exiv2 -kM"set Iptc.Application2.FixtureId String $FIXID" $FILE
                exiv2 -kM"set Iptc.Application2.ObjectName String $OBJNM" $FILE
                exiv2 -kM"set Iptc.Application2.SubLocation String $LOCN" $FILE
pic=$[pic+1]
done
exec 5<&-
for file in $(ls *.jpg);
do
        striM="$file"
        j=${file:(-4)}
        k=${file%????????}
        newname="$k$j"
        echo -e "File $file's new name will be $newname."
done
for file in $(ls *.jpg);
        do
                striM="$file"
                j=${file:(-4)}
                k=${file%????????}
                newname="$k$j"
                mv $file $newname
                exiv2 -M"set Xmp.iptc.SubjectCode XmpBag $striM" -k $newname
                echo -e "File $file has been renamed."
done

When I run it, what seems to happen is that the shell (subshell?) performs the renaming and then invokes Exiv2 to do the tagging. But of course at that point I'm getting a lot of
Code:

Error: fooswitter99900blon.jpg - Unable to open file
type messages from the latter.

As I look at this script this morning, it occurs to me that the BASH shell is performing the task which it can do in its default IFS -- the renaming -- and then giving that up and tagging under the "while ifs=','" customized one.

Is there a way to change the "order of attack," ie, write the script to perform the tagging function first and then rename (which is what I had in mind when I wrote it) the files?

BZT

MTK358 06-21-2011 11:07 AM

Could you at least tell me at what line in the script does the error occur?

grail 06-22-2011 01:34 AM

So i think we have covered this before, but using ls to feed a loop is generally a bad idea if word splitting can occur.
The first for loop does nothing so I am not sure why that is there.

Other than that, I am with MTK358 in that we need to be told where the issue is occurring before we can really help as your explanation is a little vague.

Also, have you tried putting set -x at the start of the script to see if what you expect is occurring where you want (or at least provide exact location of where the process
is breaking down)?

SilversleevesX 06-22-2011 03:09 AM

I was thinking about all this AFK, and I realized that having two loops in the script was the wrong way to go about it. If it tagged in the "while IFS= / do" loop, I reasoned, then adding the renaming task to that loop should make everything work without errors. Whatever the "do-this first, do this-second" inherent in BASH's handling of tasks, if you put everything in one loop, it should (and did) work.

The script as I rewrote it is on another machine, but I'll try to approximate the way I fixed it here:
Code:

...
j=${FILE:(-4)}
k=${FILE%????????}
newname="$k$j"
echo -e "File $FILE's new name will be $newname."
mv $FILE $newname
exiv2 -M"set Xmp.iptc.SubjectCode XmpBag $FILE" -k $newname
echo -e "File $FILE has been renamed."

All the foregoing appears in between the last exiv2 -kM"set..." command and the lines done and exec 5<&-, in other words the end of both the loop and the reading in/out of the file "fields.txt".

At any rate it works. Just took a little time to think about how to approach it.

BZT


All times are GMT -5. The time now is 05:21 PM.