LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (http://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   How to access & use command line utilities in bash scripts? (spec. SoX) (http://www.linuxquestions.org/questions/linux-newbie-8/how-to-access-and-use-command-line-utilities-in-bash-scripts-spec-sox-4175456059/)

jarednielsen 03-29-2013 03:30 PM

How to access & use command line utilities in bash scripts? (spec. SoX)
 
Hi all,
Stumped on a project. My question is: how do I use command line utilities in a bash script?

I'm writing a script that I want to access SoX. I want to iterate through a directory of .ogg files, grab the length of each file, do some math to determine the speed at which to process the file so that all of the files in the directory will be the same length.

Here's what I've got:
Code:

#!/bin/bash

a=1
for i in *.ogg; do
        trackLength=sox --i -D "$i"
        echo ${trackLength}
        trackSpeed=(${trackLength} / 1000)
        echo ${trackSpeed}
        new=$(printf "converted/%03d.ogg" ${a})
        sox "$i" ${new} speed ${trackSpeed}
        let a=a+1
done

The problem I'm encountering is in the first call on SoX:
Code:

trackLength=sox --i -D "$i"
returns:
Code:

./test.sh: line 5: --i: command not found
But running this snippet outside of a bash script works fine.

I next tried putting the first SoX call in quotes, which, when run, only echos the call itself not the integer I'm looking for.

How do I go about doing this?

Any help is greatly appreciated. Many thanks in advance.

suicidaleggroll 03-29-2013 03:44 PM

Quote:

Originally Posted by jarednielsen (Post 4921222)
The problem I'm encountering is in the first call on SoX:
Code:

trackLength=sox --i -D "$i"
returns:
Code:

./test.sh: line 5: --i: command not found
But running this snippet outside of a bash script works fine.

Doubtful

Perhaps running
Code:

sox --i -D file.ogg
works fine on the command line, but running
Code:

trackLength=sox --i -D file.ogg
will not

You need to wrap commands in $() in order to run them that way, just like you're doing with your printf command a few lines down. A BASH script is nothing more than a sequence of ordinary commands, all of which can be run on the normal command line in the exact same way.

Also,
Code:

trackSpeed=(${trackLength} / 1000)
will most likely not work in the way you expect. BASH can only do rudimentary integer math, you probably want to use bc for that calculation:
Code:

trackSpeed=$(echo "$trackLength / 1000" | bc -l)

jarednielsen 03-29-2013 05:49 PM

Thanks!
Yes, I meant "sox --i -D file.ogg". Should have clarified.
Also, thanks for pointing me in the direction of bc.
That would have been my next question.

David the H. 03-30-2013 12:12 PM

Code:

trackSpeed=(${trackLength} / 1000)
Not to mention that this isn't arithmetic expression syntax anyway, but the pattern for setting an array.


For the most part it looks like pretty good. Just a fcouple more points, starting with how I can't get "sox --i" to work for me. For some reason it balks at the syntax. :scratch: But "soxi -D" does work.

Second, always remember to quote your variables and other parameters. It may not matter much here, since you're only dealing with digits, but it's very important to get into the habit of doing it properly.

The rest is mostly just a matter of streamlining (untested, but should work):


Code:

#!/bin/bash

for i in *.ogg; do

        trackLength=$( soxi -D "$i" )
        echo "$trackLength"
        trackSpeed=$( bc <<<"scale=8 ; $trackLength / 1000" )
        echo "$trackSpeed"
        printf -v new "converted/%03d.ogg" "$(( ++a ))"
        sox "$i" "$new" speed "$trackSpeed"

done

In case you aren't aware, "++a" is the pre-increment operator. It adds one to the variable just before it's used. So the first time you use it it will equal 1. The opposite post-increment operator "a++", adds the number just after it's used.

And as you can see, bash's version of printf has an option for directly setting the output to a variable, instead of printing it to stdout.

I added a scale to the bc calculation to specify the decimal precision, instead of the "-l" mathlib option used above. And I used a here string to pass it the expression, instead of echo+pipe. It's a little cleaner and means one less forked sub-shell.


All times are GMT -5. The time now is 04:15 PM.