« Timezone surprise for U.S. systems | Main | replay-log - resubmit syslog data back to syslog »

Shell Quoting Gotcha

#!/bin/sh FILE=$1 ls $FILE

The above Bourne shell code works as expected, until a filename with a space enters the equation. Then things fall apart:

$ cat test # !/bin/sh FILE=$1 ls $FILE $ sh test /etc/passwd /etc/passwd $ touch "a file" $ sh test "a file" ls: a: No such file or directory ls: file: No such file or directory

Harmless in this test case: the script fails with an somewhat decipherable error. At worst, highly unexpected and unlogged behavior ensues. For example, an install script shipped with iTunes 2.0 ran into this problem, and sometimes erased entire disks.

An ugly workaround entails quoting anything that might be affected by this problem:

#!/bin/sh FILE=$1 ls "$FILE"

One could also mess with the IFS variable, though that change would affect all sorts of operators that act on IFS delimited data.

I instead favor Perl over shell code, which has the benefit of avoiding the shell (excepting various unsafe functions detailed in perlsec), and offering testable code through the -c command line argument and various test modules, such as Test::More.

A quoting gotcha aside, too many scripts (for the Bourne shell or other languages) suffer from a lack of test driven development. If possible, move code to modules, where each routine may be tested, in addition to sets of routines and then the entire script. Fragile black boxes that only offer inputs and outputs with no insight into the various substeps will never be as safe.

Technorati Tags: ,