Linux, programming, computers and life

June 16, 2007

some bash scripting, named pipes and traps

Filed under: CLI, programming, linux

Recently, i needed to convert a lot of mp4 files to mp3 format. Well, time for some scripting i thought to myself, time to improve my bash skills :) . And, actually, i learned several things from this simple task.
First, and pretty interesting one is named pipes.  In my script i used mplayer to convert mp4 to wav format. And then, lame in order to convert the wav to mp3.  So, generally speaking, there’s a need in temporary file which takes disk space and time to write and to delete. A lot of linux applications have the possibility to write their output to standard output, allowing to use shell pipes to pass it to other applications (which know to get their input from standard input). I did not found such an option in mplayer, but, in the back of my head i remembered it’s possible to create named pipe on linux. So, instead of creating the temporary file, i create named pipe (using mkfifo command) and use it as a channel from mplayer to lame. This allows me to parallelize them and hopefully reduces disk writes - which should give substantial speed improvement.
Second, named pipe (or any other temporary file) needs to be deleted in the end of the script… even if the script was stopped using Ctrl-c or kill/pkill commands. There’s nice thing named trap in bash which allows to execute certain code when signals arrive - which is exactly what happens on Ctrl-c or other ways of stopping an application in the middle of it’s work.
I think it’s enough lessons for one small script. Here it comes:

#! /bin/bash

if [[ “$#” != “2″ && “$#” != “1″ ]]
then
echo “Usage: $0 file .mp4 [file .mp3]”
exit 1
fi

IN_FILE=$1

if [[ “$#” == “1″ ]]
then
OUT_FILE=`echo $IN_FILE | sed -s ’s/mp4$/mp3/’`
else
OUT_FILE=”$2″
fi

# if output file already exists - exit
if [ -f “$OUT_FILE” ]
then
echo “\”$OUT_FILE\” already exists!”
exit 1
fi

# create named pipe:
PIPE_NAME=”`mktemp -u`.$$.tmp_named_pipe”

# make sure it’s deleted anyway:
trap “{ rm -f “$PIPE_NAME” ; exit 255; }” EXIT

mkfifo “$PIPE_NAME”

# mp4 -> pipe(wav):
mplayer -vc null -vo null -ao pcm:fast -ao pcm:file=”$PIPE_NAME” “$IN_FILE” &> /dev/null &

# pipe(wav) -> mp3:
lame -b 32 “$PIPE_NAME” “$OUT_FILE”

rm -f “$PIPE_NAME”
exit 0

Technorati Tags: , , , , , ,

Get free blog up and running in minutes with Blogsome
Theme designed by Gary Rogers