1

I would like to count the number of outputs produced by this loop

cd /System/Library/Extensions
find *.kext -prune -type d | while read d; do
     codesign -v "$d" 2>&1 | grep "invalid signature"
done

How can I store or count the outputs? If tried with arrays, counters etc. but it seems I can't get anything outside of that loop.

1
  • you need the count for each codesign -v "$d" 2>&1 or overall count of the while loop? Commented Nov 8, 2014 at 10:59

2 Answers 2

3

To obtain the number of lines produced by the while loop, the wc word count can be used

cd /System/Library/Extensions
find *.kext -prune -type d | while read d; do
     codesign -v "$d" 2>&1 | grep "invalid signature"
done | wc -l
  • wc -l the -l option counts the number of lines in the input, which is piped to the output of while

Now if you need to count the number of grep outputs in each iteration of the while loop, the -c option of grep would be usefull.

cd /System/Library/Extensions
find *.kext -prune -type d | while read d; do
    codesign -v "$d" 2>&1 | grep -c "invalid signature"
done
  • -c Suppress normal output; instead print a count of matching lines for each input file
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot! the wc -l command did the trick. Two things I ended up changing: 1) I added "| tr -d ' '" after "wc -l", to remove a couple unwanted spaces that were appearing in the output. 2) I stored the result in a variable by wrapping the code as such: output=$(code)
@DavidD You are always welcome :) glad to know i was of some help
1

classical difficulty in subshell is to pass variables back.

here one way to get this information back :

cd /System/Library/Extensions

RESULT=$(find *.kext -prune -type d | {
# we are in a sub-subshell ... 
GCOUNT=0
DIRCOUNT=0
FAILDIR=0
while read d; do
     COUNT=$(codesign -v "$d" 2>&1 | grep -c "invalid signature")
     if [[ -n $COUNT ]]
     then
     if [[ $COUNT > 0 ]]
     then
         echo "[ERROR] $COUNT invalid signature found in $d" >&2
         GCOUNT=$(( $GCOUNT + $COUNT ))
         FAILDIR=$(( $FAILDIR + 1 ))
     fi
     else
     echo "[ERROR] wrong invalid signature count for $d" >&2
     fi
     DIRCOUNT=$(( $DIRCOUNT + 1 ))
done
# this is the actual result, that's why all other output of this subshell are redirected
echo "$DIRCOUNT $FAILDIR $GCOUNT"
})

# parse result integers separated by a space.
if [[ $RESULT =~ ([0-9]+)\ ([0-9]+)\ ([0-9]+) ]]
then
    DIRCOUNT=${BASH_REMATCH[1]}
    FAILDIR=${BASH_REMATCH[2]}
    COUNT=${BASH_REMATCH[3]}
else
    echo "[ERROR] Invalid result format. Please check your script $0" >&2
fi

if [[ -n $COUNT ]]
then
    echo "$COUNT errors found in $FAILDIR/$DIRCOUNT directories"
fi

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.