Mailinglist Archive: opensuse (2772 mails)

< Previous Next >
Re: [opensuse] Another Bash scripting question
  • From: David Bolt <bcrafhfr@xxxxxxxxxx>
  • Date: Mon, 19 May 2008 10:47:55 +0100
  • Message-id: <$wHdXBJLzUMIFweI@xxxxxxxxxxxxxxxxxxx>
On Sun, 18 May 2008, Sam Clemens wrote:-

Rodney Baker wrote:
OUTFILE=${file/%wav/mp3}
^^^^^^^^^^^^^^^^^
WHAT?????


Clue for the clueless...

Oh dear. That was a silly thing to do. I really do hope that you washed
your feet recently because, if not, that's going to leave a bad taste
behind if you haven't.

If you had bothered to COMMENT YOUR CODE, you would
have discovered this error right off the bat.

What exactly is the error with that line? Do you have any idea what it
does? Have you tried it to find out? I'm guessing you haven't because,
if you had, you wouldn't have mentioned it. Here's an example of what it
does:

davjam@donnas:~> i="this is a test to see if the expression \${i/%wav/mp3}
correctly removes a trailing.wav"
davjam@donnas:~> echo "${i}"
this is a test to see if the expression ${i/%wav/mp3} correctly removes a
trailing.wav
davjam@donnas:~> echo "${i/wav/mp3}"
this is a test to see if the expression ${i/%mp3/mp3} correctly removes a
trailing.wav
davjam@donnas:~> echo "${i/%wav/mp3}"
this is a test to see if the expression ${i/%wav/mp3} correctly removes a
trailing.mp3

As you can see, it uses the string replacement function of bash, where
${var/something/else} looks at the contents of ${var} and replaces the
first instance of "something" with "else". If ${var//something/else} was
used instead, all instances of "something" would be replaced by "else".
The addition of the '%' slightly modifies the behaviour so
${var/%something/else} looks for the last instance of "something" and
replaces it with "else".

And if you get in the habit of writing comments BEFORE
YOU WRITE THE CODE, you'll discover that your rate of
bug production drops drastically (both in bugs/hour
and also in bugs/lines of code).

Well, one bug I spotted was that there's at least one major problem that
goes unchecked. What happens if ${INFILE} == ${OUTFILE}? I'd hazard a
guess that sox would open ${file}[0] to read, then open ${OUTFILE} for
writing, then see ${file} has just become a 0-length file and terminate.
That sort of problem is easily fixed with a simple addition of:

# skip if input and output files are the same
#
[ "${file}" == "${OUTFILE}" ] && continue

to the loop.

Another question is, is the script supposed to only process the files in
the current directory, or all sub-directories as well. If it's just the
current directory, it would be much simpler to use:

# look for files only within the current directory
#
find -maxdepth 1 -type f -name "*.wav" | \
while read file
do

If it's the latter, using:

# look for files within the current directory, and any sub-directories
#
find -type f -name "*.wav" | \
while read file
do

would ensure that only .wav files are processed, both of which removes
the requirement for the "${file}" == "${OUTFILE}" check, and also makes
sure that nothing happens when there are no files to process.

The only time this is going to break is when a filename contains an
ASCII character 0x0a, or line feed. However, anyone stupid enough to
include one of those in a filename should expect breakage and can figure
out how to fix the script to handle those files themselves.


Regards,
David Bolt

--
Team Acorn: http://www.distributed.net/ OGR-P2 @ ~100Mnodes RC5-72 @ ~15Mkeys
SUSE 10.1 32bit | openSUSE 10.2 32bit | openSUSE 10.3 32bit | openSUSE 11.0b1
SUSE 10.1 64bit | openSUSE 10.2 64bit | openSUSE 10.3 64bit
RISC OS 3.6 | TOS 4.02 | openSUSE 10.3 PPC | RISC OS 3.11
--
To unsubscribe, e-mail: opensuse+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: opensuse+help@xxxxxxxxxxxx

< Previous Next >
Follow Ups