[kw-pm] trying to diff two files which contain '$' in their names

Cees Hek ceeshek at gmail.com
Wed Mar 16 19:35:39 PDT 2011


On Wed, Mar 16, 2011 at 9:41 PM, Robert P. J. Day <rpjday at crashcourse.ca> wrote:
>
[snip]
>
>  the problem is that the filenames sometimes contain a literal dollar
> sign as part of the name (don't ask).  so a simplified demo of the
> problem would be:
>
[snip]
>
>  i've tried to backslash escape various things but no success.  what
> bit of magic am i missing?

The problem is that the shell is expanding your command and hence you
need to make sure everything is escaped properly.  The safer way to
handle this is to not involve the shell at all.  In order to do that
you need to be able to pass the options one at a time in a list, and
backticks don't allow that.  perldoc perlsec gives a safe way of doing
this with fork and exec:

         Here's a way to do backticks reasonably safely.  Notice how
the "exec" is not called with
         a string that the shell could expand.  This is by far the
best way to call something that
         might be subjected to shell escapes: just never call the shell at all.

               use English '-no_match_vars';
               die "Can't fork: $!" unless defined($pid = open(KID, "-|"));
               if ($pid) {           # parent
                   while (<KID>) {
                       # do something
                   }
                   close KID;
               } else {
                   my @temp     = ($EUID, $EGID);
                   my $orig_uid = $UID;
                   my $orig_gid = $GID;
                   $EUID = $UID;
                   $EGID = $GID;
                   # Drop privileges
                   $UID  = $orig_uid;
                   $GID  = $orig_gid;
                   # Make sure privs are really gone
                   ($EUID, $EGID) = @temp;
                   die "Can't drop privileges"
                       unless $UID == $EUID  && $GID eq $EGID;
                   $ENV{PATH} = "/bin:/usr/bin"; # Minimal PATH.
                   # Consider sanitizing the environment even more.
                   exec 'myprog', 'arg1', 'arg2'
                       or die "can't exec myprog: $!";
               }

This important thing to notice here is that in the 'exec' call all
arguements (inlcuding the command name and switches) are passed
individually as a list, instead of as one big long string.

If that is too ugly/messy for you, then look at a module to make
things easier, like IPC::Run.

Cheers,

Cees


More information about the kw-pm mailing list