Friday, December 3, 2010

Bash named pipes

Pipes are a unix staple. They're core to the unix philosophy of modularity. Bashes named pipes just knock this up a notch.

Lets say we have two directories that should have contain the same files, but one is on a case insensitive file system, so some files might differ in case. We could do this, using normal pipes to process the directory entries.

ls dir1 | tr "[:lower:]" "[:upper:]" | sort > dir1_contents
ls dir2 | tr "[:lower:]" "[:upper:]" | sort > dir2_contents
diff dir1_contents dir2_contents

But this is kind of hacky and creates two temporary files.

Bash named pipes lets you use the output of a pipe system in place of a filename. Its almost like the pipes were written into temporary files and the files deleted afterwards, but no disk space is consumed by the files.

diff <( ls dir1 | tr "[:lower:]" "[:upper:]" | sort ) <( ls dir2 | tr "[:lower:]" "[:upper:]" | sort )

Much neater.

Mind you I haven't used these often, but if you know they exist they can make some painful multistep processes much simpler.