I use Cygwin on Windows. I finally got around to solving an annoyance that has been bugging me for a while -- Bash pipelines with paths containing spaces don't work as expected. For example, let's say I run a command that produces a path containing spaces as its output:
2009-08-31 01:16:32 Administrator@p43400e ~
$ ls -d /cygdrive/c/Documents\ and\ Settings/
/cygdrive/c/Documents and Settings/
If I naively pipe that to another command, Bash breaks up the paths at the spaces (see 'man bash' and IFS) and sends the pieces along, with confusing results:
2009-08-31 01:16:50 Administrator@p43400e ~
$ ls -d /cygdrive/c/Documents\ and\ Settings/ | xargs ls
ls: cannot access /cygdrive/c/Documents: No such file or directory
ls: cannot access and: No such file or directory
ls: cannot access Settings/: No such file or directory
The same thing happens with backticks:
2009-08-31 01:16:55 Administrator@p43400e ~
$ ls `ls -d /cygdrive/c/Documents\ and\ Settings/`
ls: cannot access /cygdrive/c/Documents: No such file or directory
ls: cannot access and: No such file or directory
ls: cannot access Settings/: No such file or directory
The solution is to delimit the paths with nulls and call 'xargs' with the '-0' option (see 'man xargs'):
2009-08-31 04:04:36 dpchrist@p43400e ~
$ ls -d /cygdrive/c/Documents\ and\ Settings/ | perl -ne 's/\n/\00/; print' | xargs -0 ls -dl
drwxrwxr-x+ 9 Administrators SYSTEM 0 Aug 30 01:19 /cygdrive/c/Documents and Settings/
The Perl one-liner can be converted into a Bash alias and put into .bashrc:
2009-08-31 04:14:45 dpchrist@p43400e ~
$ vi .bashrc
alias nl2null="perl -ne 's/\n/\00/; print'"
Which saves some typing:
2009-08-31 04:16:03 dpchrist@p43400e ~
$ ls -d /cygdrive/c/Documents\ and\ Settings/ | nl2null | xargs -0 ls -dl
drwxrwxr-x+ 9 Administrators SYSTEM 0 Aug 30 01:19 /cygdrive/c/Documents and Settings/