1

I'm trying to write a bash script that analyzes the video files in a folder to output the total video duration in that immediate folder and the video duration in that folder plus all its sub-folders. My code is:

#!/bin/bash

### Outputs the total duration of video in each folder (recursively).
##  Incase an argument is not provided, the basefolder is assumed to be pwd.

# Defining custom Constants & functions
RED='\033[1;31m'
GREEN='\033[1;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
NC='\033[0m' # No Color

echoErr() { 
    echo -e "${RED}[ERROR]${NC}: $@" 1>&2
    exit
}

folderTime() {
    echo $(find . -maxdepth 1 -iname '*.mp4' -exec ffprobe -v quiet -of csv=p=0 -show_entries format=duration {} \; | paste -sd+ -| bc)
}

# Setting the base directory
if [ "$#" -lt 1 ]; then
    baseDir="$(pwd)"
else
    baseDir="$1"
fi

cd "$baseDir" || echoErr "Error switching to $baseDir"

# Actual calculation of the total video duration in each folder - using a function.
totalTime=0
function calcTime() {
    local incomingTime=$totalTime
    local newTotalTime=0
    local immediateTime=0
    newTotalTime=immediateTime=$(folderTime)
    for f in "$1"*
    do
        if [ -d "$f" ]; then
            cd "$f" || echoErr "Can't switch to $f" 
            calcTime "$f"
            newTotalTime=$(( $newTotalTime + $totalTime ))
        fi
    done
    totalTime=$(( $newTotalTime + $incomingTime ))
    echo -e "The duration of video in just $f is : \t\t${BLUE}$immediateTime${NC}"
    echo -e "The Total duration of video in $f and subfolders is : \t${GREEN}$totalTime${NC}"
}
calcTime "$baseDir"

The above code produces no output what so ever, but the neither does the execution halt. I'm pretty sure being new to bash scripting, I've made some kind of error(s), but for the life of me, can't figure out exactly what it is. Please help.

Also, please tell me any and all ways of improving this script. Thanks!

  • Run with bash -x to see where it gets stuck. Also newTotalTime=immediateTime=$(folderTime) won't work the way you think it will. – muru Oct 25 '17 at 3:50
  • @muru Please tell me what happens when newTotalTime=immediateTime=$(folderTime) is executed. I'm trying to improvise due to the lack of a true return value in bash. – Somenath Sinha Oct 25 '17 at 3:58
  • 1
    Check the output of bash -c 'a=b=$(echo foo); declare -p a b'. – muru Oct 25 '17 at 4:00
  • @muru How does one use bash -x? I can't find a good reference for it. – Somenath Sinha Oct 25 '17 at 4:06
  • 2
    I'm pretty sure this is just going to cd into . over and over again if that's what you start it on. It should still crash eventually, so if it doesn't halt I'm not sure. – Michael Homer Oct 25 '17 at 4:09
3

You accidentally coded yourself into a recursive loop. The problem is inside your calcTime() function:

for f in "$1"*

When you call pwd, it leaves off the trailing slash. So, for f in "$1"* turns into for f in "/my/current/directory*", which always sets f to /my/current/directory.

Since you call calcTime() from within that loop, it just recurses endlessly. If you change the for loop definition to the following, I think it should behave better:

for f in "$1"/*

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.