I'm trying to automatically convert flac files moved to a folder into mp3 in another folder.

My current line of code is this:

inotifywait -m -r -q -e moved_to --format "'%w%f'" ~/test |  xargs -I x flac -cd x - | lame -b 320 - /media/1tb/x.mp3

To explain how this works so far, inotifywait monitors ~/test recursively for files moved there, outputting the path and filename to a pipe. xargs takes that name and creates the proper flac command, replacing x with the filename and decoding the file to another pipe. In the new pipe lame processes the output of flac into mp3 under /media. I want xargs to either reach across the pipe in some way, replacing the x in the lame command or in some way send it to a variable both commands can access or something. I tried messing around with named pipes and that jazz but the fact that there is actual data being piped between the two commands has me in way over my head.

2 Answers 2


If I understand correctly, you want to fire up one instance flac … | lame … for each input line, and interpolate the input into the arguments to both commands.

Since you need xargs to start a pipeline, you need to make it start a program that's capable of creating pipelines, i.e. a shell.

inotifywait -m -r -q -e moved_to --format "%w%f" ~/test |
xargs -l sh -c 'flac -cd "$0" - | lame -b 320 - "/media/1tb/$0.mp3"'

Alternatively, have the calling shell read lines one by one and run the pipeline.

inotifywait -m -r -q -e moved_to --format "%w%f" ~/test |
while IFS= read -r file; do
  flac -cd "$file" - | lame -b 320 - "/media/1tb/$file.mp3"

Note that the format %w%f produces an absolute path, to which you're prepending /media/1tb and appending .mp3. If you want to strip off the directory part of the file in the lame command, change $file to ${file##*/}. If you want to strip off the extension, change $file to ${file%.*}. If you want to do both, you'll have to do it in two steps. If you want to reproduce the directory hierarchy under /media/1tb, you can use mkdir -p.

cd ~/test
inotifywait -m -r -q -e moved_to --format "%w%f" . |
while IFS= read -r file; do
  [ -f "$file" ] || continue; # skip directories and other special files
  dir=${file%/*}; file=${file##*/}
  mkdir -p "/media/1tb/$dir"
  flac -cd "$dir/$file" - | lame -b 320 - "/media/1tb/$dir/${file#.*}.mp3"

You could try something like:

inotifywait -m -r -q -e moved_to --format "'%w%f'" ~/test \
    | while read x; do \
        flac -cd "$x" - | lame -b 320 - "/media/1tb/$x.mp3"
  • 1
    while read … is a solution, but then, drop xargs. What you wrote just doesn't make sense: where do you think xargs is getting its input? And you should quote things properly, it's common for music file names to contain spaces. Dec 23, 2013 at 1:33
  • @Gilles It wasn't/isn't clear to me exactly what the OP is doing, which is why I said "you could try something like" and "I'm not sure if the xargs bit is true to your intentions" etc. So not the best answer but a hint in the right direction, I think. Have fixed the quoting issue and removed xargs.
    – goldilocks
    Dec 23, 2013 at 12:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .