differenceengine has asked for the wisdom of the Perl Monks concerning the following question:

Hey there, I seek the wisdom of some monks!

Half a day spent trying to figure this out :-(, something i'm missing or don't understand properly for sure.

I want to use shell brace expansion in backticks to delete some files. Neater than doing rm a, rm b, rm c etc. The shell or Perl (not sure) always treats the { .. } literally. Anyone know how I can do this?

I've tried using qx'...', qx(...), `bash -c "..."`, and all sorts of escapes with backslashes, can't fathom it and unusually Google has not been my friend ;-)

$ touch perl.err $ touch perl.tst $ ls {perl.err,perl.tst} perl.err perl.tst $ perl -e '`rm {perl.err,perl.tst}`'; rm: cannot remove `{perl.err,perl.tst}': No such file or directory $ rm {perl.err,perl.tst} $

I'm developing for FreeBSD 8 Perl 5.10 using stock /bin/sh but I observe the same behaviour on Linux with bash. Cheers.

Replies are listed 'Best First'.
Re: Backticks and shell brace expansion
by FunkyMonk (Bishop) on Jul 31, 2011 at 20:48 UTC
    You could let perl handle the deletion using unlink and glob:

    unlink glob q<{perl.err,perl.tst}>; # or, glob q<perl.{err,tst}>

    Or, if all you want to do is delete a list of files:

    unlink qw< perl.err perl.tst >;

Re: Backticks and shell brace expansion
by JavaFan (Canon) on Jul 31, 2011 at 21:30 UTC
    I cannot reproduce the problem:
    $ touch perl.err perl.tst $ ls perl.* perl.err perl.tst $ perl -e '`rm {perl.err,perl.tst}`'; $ ls perl.* ls: perl.*: No such file or directory
    This is on Linux and GNU bash. I think that a real Bourne shell does not have brace expansion.

    What happens if you do rm {perl.err,perl.tst} in an instance of /bin/sh? Or rather, what happens if you do /bin/sh -c "rm {perl.err,perl.tst}"?

      Thanks for the responses!

      JavaFan, you have it there... on the Linux (Ubuntu) box /bin/sh is a symlink to dash which doesn't have brace expansion. I assumed /bin/sh would be a link to bash but it ain't. On the FreeBSD, I thought I was using /bin/sh but actually my user accounts are set to use tcsh.

      Perl always calls /bin/sh so that's why brace expansion doesn't work. On both systems Perl is not using a shell that supports it (whereas my terminal sessions are).

      Thankyou FunkyMonk for the unlink/glob hint. Looks like a neater, more Perl-ish way of doing what I need so I will look into it.

      Thanks again all.

Re: Backticks and shell brace expansion
by anonymized user 468275 (Curate) on Jul 31, 2011 at 20:50 UTC
    Back ticks spawn the shell set for the unix account. That shell is trying to include the brackets and comma in the filename.

    One world, one people