title: "command not found" errors when executing TCL script in OSX
body: <p>I'm trying to execute <a href="http://wiki.tcl.tk/41305" rel="nofollow">this TCL script</a>, which should batch normalise a folder of mp3's.  I'm on OSX Yosemite (ffmpeg fully installed).  The line is:</p>
  
  <pre><code>./normalise.tcl mp3folder
  </code></pre>
  
  <p>which (inc. sudo) returns:</p>
  
  <pre><code>./normalise.tcl: line 37: proc: command not found
  ./normalise.tcl: line 38: global: command not found
  ./normalise.tcl: line 40: switch: command not found
  ./normalise.tcl: line 42: puts: command not found
  ./normalise.tcl: line 43: syntax error near unexpected token `}'
  ./normalise.tcl: line 43: `        }'
  </code></pre>
  
  <p>.. and then directs shell to the inbuilt help documentation.  I have no experience of this language so am reading up, but haven't come across anything so far to explain it.  Very grateful for an idea what's going wrong.</p>
  
  <hr>
  
  <p>Edit</p>
  
  <p>The <code>-d</code> option suggested in script comments seems to have no effect.</p>
  
  <p>The full script:</p>
  
  <pre><code>#!/bin/sh
  #\
  exec tclsh "$0" ${1+"$@"}
  
  # Copyright 2015 Tholis Biroi (tholis DOT biroi AT yahoo DOT it)
  #
  # This file is part of 'normalize.tcl'.
  # 'normalize.tcl' is free software: you can redistribute it and/or modify 
  # it under the terms of the GNU General Public License as published by
  # the Free Software Foundation, either version 3 of the License, or 
  # (at your option) any later version.
  # 'normalize.tcl' is distributed in the hope that it will be useful, but 
  # WITHOUT ANY WARRANTY; without even the implied warranty of 
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
  #
  # See the GNU General Public License for more details.
  # You should have received a copy of the GNU General Public License 
  # along with 'normalize.tcl'. If not, see http://www.gnu.org/licenses/.
  #
  #
  #
  # 'normalize.tcl' is a simple TCL script that drives 'ffmpeg' to normalise
  # audio levels for a group of mp3 files.
  # For each mp3 file found into a directory, it reads the mean volume level, 
  # calculates the average level among various files and adjusts the volume
  # level of each of them.
  #
  
  # Global debugging variable
  # To override this option set '-d' on the command line
  set debugOn false
  
  # log --
  #
  # puts "" wrapper 
  #
  proc log {label args} {
      global debugOn
  
      switch $label {
          "info" {
              puts {*}$args
          }
          "error" {
              puts "error: [join {*}$args]" 
          }
          "warning" {
              puts "warning: [join {*}$args]" 
          }
          "debug" {
              if {$debugOn == "true"} {
                  puts "debug: [join {*}$args]" 
              }
          }
          default {
              # do nothing in any case
          }
      }
  }
  
  
  # get_volumes --
  #
  # Exec 'ffmpeg' in order to get the volume mean level
  #
  #
  proc get_volume {mp3} {
      if {$mp3 == {}} {
          log error "Empty file name."
          return {}
      }
  
      # Set volume variable
      set volume {}
  
      # Set 'ffmpeg' command
      set cmd "ffmpeg  -i \"$mp3\" -af \"volumedetect\" -f null /dev/null"    
      log debug "'ffmpeg' cmd= $cmd"
  
      # Exec 'ffmpeg'
      if {[catch {eval exec -ignorestderr $cmd 2&gt;@1} out]} {
          log error "'ffmpeg' execution command failed."
          log debug "reason= $out"
          return {}
      }
  
      # In order to avoid 'case sensitive' parsing, the output of the 
      # command is converted to uppercase
      set Out [string toupper $out]    
      log debug "'ffmpeg' out= $Out"
  
      # Now scan the out a line at time searching for 'MEAN_VOLUME:' 
      # output string label
      set lines [split $Out "\n"]
  
      foreach line $lines {
          log debug "$line"
          # first of all search for 'VOLUMEDETECT' string and if foud
          # search for 'MEAN_VOLUME:' string.
          if {[string first VOLUMEDETECT $line] == -1} {
              # Not found, skip line parsing 
              continue
          }
  
          # 'VOLUMEDETECT' string found, search for 'MEAN_VOLUME' string
          set pos [string first MEAN_VOLUME $line]
          if { $pos != -1} {
              set start [expr {$pos + 11}]
              set volStr [string range $line $start end]
              log debug "volStr= $volStr"
  
              # Extract and trim the first word as volume
              set words [split $volStr]
              log debug "words= $words"
              set volume [string trim [lindex $words 1]]
              log debug "volume= $volume"
          }
      }
  
      return $volume
  } ;# end get_volume
  
  
  # set_volume --
  #
  # Exec 'ffmpeg' to re-encode the mp3
  #
  proc set_volume {mp3 actualVol targetVol} {
      if {($mp3 == {}) || ($actualVol == {}) || ($actualVol == {})} {
          log error "One or more parameter are empty"
          return {}
      }
  
      # Create filename output
      set mp3Root [file rootname $mp3]
      set mp3OutFile "${mp3Root}.norm.mp3"
  
      # If normalized file already exists, will be deleted
      if {[file exists $mp3OutFile]} {
          catch {file delete -force -- $mp3OutFile}
      }
  
      # calculate the delta volume
      set deltaVol [expr {$targetVol - $actualVol}]
  
      # Set 'ffmpeg' command
      set cmd "ffmpeg -y -i \"$mp3\"  -af \"volume=${deltaVol}dB\" \"$mp3OutFile\""
  
      # Exec 'ffmpeg'
      if {[catch {eval exec -ignorestderr $cmd 2&gt;@1} out]} {
          log error "'ffmpeg' execution command failed."
          log debug "reason= $out"
          return {}
      }   
  
      # For debug purposes
      set Out [string toupper $out]    
      log debug "'ffmpeg' out= $Out"
  
      return $deltaVol
  } ;# end set_volume
  
  
  # byebye --
  #
  proc byebye {} {
      log info ""
      log info "Bye!"
      log info ""
  } ;# end byebye
  
  
  # print_help --
  # 
  # Prints a little help
  #
  proc print_help {} {
      global argv0
  
      log info ""
      log info "Usage: $argv0 \[-h|--help\]|&lt;mp3 dir&gt;"
      log info ""
      log info "-h|--help  Print thi help"
      log info "&lt;mp3 dir&gt;  Directory path containing mp3 to normalize"
      log info ""
  
      byebye
      return
  } ;# end print_help
  
  # Main -----------------------------------------------------------------
  log info ""
  log info "MP3 normalizer v0.9 21 mar 2015"
  log info ""
  log info ""
  
  # Save current dir
  set currDir [pwd]
  log debug "Working dir= $currDir"
  
  # Control input parameters to setup working dir 
  # If no parameter is passed a little help is printed on screen
  if {$argc == 0} {
      print_help
      exit 0
  }
  
  # If more than one parameter is passed
  if {$argc != 1} {
      log error "Wrong number of arguments."
      log error "Use '-h' or '--help' option to print usage info."
  
      byebye
      exit 1
  }
  
  # If only one paramter is passed, it could be the help option or the
  # desired working path
  if {([lindex $argv 0] == "-h") || ([lindex $argv 0] == "--help")} {
      print_help
      exit 0
  }
  
  # Save the passed workDir in order to make some controls
  set workDir [lindex $argv 0]
  
  # The path passed must be a directory path
  if { ![file isdirectory $workDir] } {
      log error "The argument passed is not a valid directory path"
  
      byebye
      exit 1
  }
  
  # The argument passed must be an existing directory
  if { ![file exists $workDir] } {
      log error "Directory '$workDir' does not exists"
  
      byebye
      exit 1
  }
  
  # Move on working dir
  cd $workDir
  
  # Get the list of files in the current directory
  set mp3Files [glob -nocomplain *.mp3]
  
  if {$mp3Files == {}} {
      log info "No .mp3 files found on working dir: '$workDir'"
  
      byebye
      exit 1
  }
  
  # Exclude from this list files with exetension *.norm.mp3"
  set mp3FileList {}
  foreach mp3 $mp3Files {
      set rootFname [file rootname $mp3]
      set ext [file extension $rootFname]
  
      if {$ext == ".norm"} {
          # Skip already normalized files from mp3 list
          continue
      }
  
      lappend mp3FileList $mp3
  }
  
  
  # Init the mp3 array
  #set mp3Ar {}
  
  log info "List of file mp3 to be normalized:"
  
  # Foreach *.mp3 file 
  foreach mp3 $mp3FileList {
      log info "   '$mp3'"
  
      # Extract volumes
      set vol [get_volume $mp3]
      if {$vol == {}} {
          log warning "No volume information found for file: $mp3"
      } else {
          # Fill the array of volumes
          set mp3Ar($mp3) $vol
      }
  }
  
  log info ""
  
  # parray only for debugging
  #parray mp3Ar
  
  # Calculating the average volume
  set avgVol 0
  set mp3List  [array names mp3Ar]
  set numFiles [llength $mp3List]
  
  foreach mp3 $mp3List {
      set avgVol [expr {$mp3Ar($mp3) + $avgVol}]
  }
  set avgVolume [expr {$avgVol/double($numFiles)}]
  set avgVol [format "%0.1f" $avgVolume]
  
  log info "Avg Volume= $avgVol"
  log info ""
  
  # Now foreach file calculate delta volume to normalize it
  log info "File normalization at $avgVol dB"
  foreach mp3 $mp3List {
      log info "    '$mp3' from $mp3Ar($mp3) to $avgVol"
      if {[set_volume $mp3 $mp3Ar($mp3) $avgVol] == {}} {
          log info "warning: Set volume failed for file '$mp3'"
      }
  }
  log info ""
  log info "Done."
  
  # Before exit return to run dir
  cd $currDir
  
  byebye
  
  exit 0
  </code></pre>