The Fugue

Counterpoint by Hans Fugal

Filter stderr

Posted by Hans Fugal Tue, 26 Aug 2008 04:19:36 GMT

I've been exploring D the language. I really do like it, but that's another post. There are a couple of D compilers, but the only viable option on OS X seems to be gdc. I installed it via MacPorts. On Leopard, gdc generates assembly that makes the FSF gcc complain "indirect jmp without `*'" over and over. The bug is known, and other than being annoying it seems harmless.

So I decided what I needed was a script that would filter out these frivolous warnings without otherwise affecting stderr, and also without changing the exit status (so make can do the right thing). This turned out to be easier said than done. Finally I stumbled on the right incantation:

#! /bin/bash
gdc=/opt/local/bin/gdc
msg="indirect jmp without"
$gdc "$@" 2> >(grep -v "$msg" 1>&2)

We redirect stderr to the named pipe corresponding to that subshell (see "Process Substitution" in the bash manpage), then we redirect grep's output to its stderr. Because grep is in a subshell, its exit status doesn't mess up the exit status of the script, which is the exit status of gdc, as it should be.

no comments |

Pipe Dream

Posted by Hans Fugal Wed, 25 Jun 2008 03:05:33 GMT

So I've been reading up on what makes organ pipes tick (ok, so they don't tick). It's very fascinating and yet very simple. It has surprised even me that it has made me think about making my own.

Now, I'm not crazy enough to build a large organ, at least not without gobs of time and money and the proper tools. I'm still nurturing the dream of building just a MIDI pedalboard, remember.

Still, there is a project that I can see myself taking on someday. I could build a positive organ. ("Positive" rhymes with "beef.") It's a little one-manual organ that has just a couple of stops. It's portable like a dresser with wheels is.

But not just any positive organ. A crazy simple positive organ. I'm thinking PVC pipe, because working with metal and wood intimidates me (and I don't have the tools). That may change before I actually build it. Who needs a case? If I'm going to build a pipe organ it's going to be naked so that people can see how an organ works. So build it onto/into a simple push cart or something. As for wind, what good is a portable organ if you have a loud motor that needs electricity? If I had cash for a nice quiet blower that would be one thing, but since I don't maybe I'll go with a simple bellows like they did in the olde days. Keyboard? Tracker's the only way to go on something like this, which means I'll have to break my anti-woodworking pact. But on a positive organ where the pipes are right there, the action should be simple.

This is very early stages of the dream, but I'm imagining 8', 4', 2', and 2 2/3'. 8' and 4' for sure. Probably 49 notes (4 octaves) on the manual. So that's 100–200 pipes. I hope my attention span is that large. Of course I can always start with one stop and go from there.

You may wonder how I'm going to fit an 8' stop in an organ I pretend will be portable. You can take a 4' pipe and cover the end and it will resonate like an 8' pipe (and though it's not made of wood will hopefully sound not entirely unlike a Gedackt).

If none of that made any sense, just click on this link and say "that'd be cool!"

no comments |

Pipelining Processes in Ruby

Posted by Hans Fugal Thu, 02 Aug 2007 21:58:00 GMT

I've occasionally needed to pipeline some processes in Ruby, especially when doing sysadmin-type tasks. You can always do:

system "foo | bar"

but that gets interpreted by the shell. That can be a problem when you need to include filenames that could have all kinds of nastiness including spaces, semicolons, exclamation points, etc. You should be shaking in your boots about now.

Well, for single processes, it's easy:

system "foo", arg1, arg2

But if you want to pipe them together it's a bit more difficult. I came up with this solution, and it seems to be working well in my "convert my cool music collection into a lame (wink) format my car stereo can understand" script:

  def pipeline(*args)
    pids, r = args.inject([[],nil]) do |memo, cmd|
      pids, rr = memo
      r,w = IO.pipe
      if (pid = fork)
        pids.push pid
        rr.close if rr
        w.close
        [pids, r]
      else
        r.close
        $stdin.reopen rr if rr
        $stdout.reopen w
        cmd = [cmd] if String === cmd
        exec *cmd
      end
    end
    r.close
    pids.each {|p| Process.waitpid(p)}
  end

  pipeline ['oggdec','-o','-',oldpath],['lame','-',newpath]

Do take the time to figure out what's going on, but don't do it without a piece of paper handy or you might sprain something.

Update

I had an error in the original post—if you don't close rr in the parent of the fork you will end up with too many open files eventually.

Posted in | 2 comments |