0

I have a code where i want to install apt packages from a file, and logging the result.

If it succeds i want to print "< packagname > install: succes" and if it fails i need to write " < packagename > install: failed" and increment a variable called failed

I have populated the reqruiments.apt with fake apt package names to make it fail.

LOGFILE=log.txt
FAILED=0
for req in $(cat requirements.apt)
    do
        apt install -y "$req" &> aptInstall.log &&
        printf "$req: Succes\n" >> $LOGFILE ||
        (printf "$req: Failed\n" >> $LOGFILE && ((FAILED++)))
    done
        printf "\n\nApt install ran with $FAILED failed packages\n"  >> $LOGFILE
        printf "###############################\n" >> $LOGFILE
        printf "\n\n" >> $LOGFILE

My log looks like this:

python-opencv-tre: Failed
build-essential-tre: Failed
python-scipy-tre: Failed


Apt install ran with 0 failed packages
###############################

I would have expected

python-opencv-tre: Failed
build-essential-tre: Failed
python-scipy-tre: Failed


Apt install ran with 3 failed packages
###############################

1 Answer 1

4

The problem is your increment of FAILED runs in another shell. When you run

(printf "$req: Failed\n" >> $LOGFILE && ((FAILED++)))

you spawn a new process; in that process FAILED is incremented, but not in your "master" process. You should remove those surrounding brackets.

printf "$req: Failed\n" >> $LOGFILE && ((FAILED++))

NOTE: suppose you want to group commands together without spawning a new process; consider using curly braces:

{ printf "$req: Failed\n" >> $LOGFILE && ((FAILED++)) ; }

An example to show this to you:

FAILED=0
for i in $(seq 1 3); do
    (echo "FAILED=$FAILED" && ((FAILED++)))
done

gives

FAILED=0
FAILED=0
FAILED=0

now remove the surrounding braces:

FAILED=0
for i in $(seq 1 3); do
    echo "FAILED=$FAILED" && ((FAILED++))
done

and you get

FAILED=0
FAILED=1
FAILED=2

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