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

I'm writing a script to run tcpreplay using the IPNAT remapping facility to test some code.

The tcpreplay call looks like this at a commandline:

tcpreplay -i eth2 -N 192.168.0.1/32:1.1.1.1/32,192.168.0.2/32:2.2.2.2/32 test.cap

When I invoke that via exec, system, or backticks for that matter, the command shows in ps so:

tcpreplay -p 1 -i eth2 -N 192.168.0.1/32 1.1.1.1/32 192.168.0.2/32 2.2.2.2/32 test.cap

missing the ":" and ",", which of course makes tcpreplay angry.

Does anyone have a suggestion for how to deal with this?
TIA,
- bill
  • Comment on how to pass colon and comma in exec args

Replies are listed 'Best First'.
Re: how to pass colon and comma in exec args
by gaal (Parson) on Nov 05, 2004 at 05:34 UTC
    Use the exec PROGRAM LIST form to call the external program. You will probably need a full path to the executable, but the shell won't mangle your arguments.

    # actually a list of tokens, not one string. exec qw{/usr/bin/tcpreplay -i eth2 -N 192.168.0.1/32:1.1.1.1/32,192.16 +8.0.2/32:2.2.2.2/32 test.cap};
      So, of course, I simplified things a bit in the post. I'm using variables for this:

      exec qw{$tcpreplay -p $pps -i $eth -N $src_ip/32:$src,$dest_ip/32:$users->{$user}->{nets}{$src} $users->{$user}->{authcap} $datacap 2>&1}

      would be the equiv to your response in my code.

      That doesn't work, tho'. I get an error about 'No such file or directory' - but the binary is in the location specified in the variable.

      I've also gone the route of creating an @arg array with each token in it, and call it so:

      exec(@args) or die .....

      and I get the result that I posted.

      Thanks!
        I also tried the qw with a different delimiter to avoid confusion and collision with my variables. :-)
Re: how to pass colon and comma in exec args
by billbabcock (Acolyte) on Nov 05, 2004 at 14:45 UTC
    I appreciate the great suggestions on this one. The net result of all still ends up being that once the ":" and "," that are part of the '-N addr1:remapaddr1,addr2:remapaddr2' arg to tcpreplay, are passed thru, they end up looking like this to tcpreplay:

    '-N addr1 remapaddr1 addr2 remapaddr2'

    which is of course, wrong as far as it's concerned.

    I appreciate the thoughts - if I solve this, I will post the result. If anyone else gets it to work, I'd love to see how.

    Thanks! - bill
Re: how to pass colon and comma in exec args
by scottb (Scribe) on Nov 05, 2004 at 20:56 UTC
    $ perl -e 'print `echo ;`;'
    
    $ perl -e 'print `echo \;`;'
    
    $ perl -e 'print `echo \\;`;'
    ;
    
    The reason this works is that the characters are interpolated by the shell that is opened, and a single backslash is interpolated by Perl. So to actually pass through a backslash, you need to send two backslashes. In other words, perl sees "\\;", the shell sees "\;", and the program sees ";".

    Update: by the way, qw won't interpolate variables as far as I know.

    - Scott

Re: how to pass colon and comma in exec args
by thospel (Hermit) on Nov 06, 2004 at 13:04 UTC
    Neither , nor : is special for /bin/sh:
    perl -wle 'system("echo ab,:cd")' prints: ab,:cd
    So something else is the cause, but we can't know what since you don't give us enough information to reproduce your problem (mind you, using the list form of system/exec/whatever is still a good idea, but not using that or bad escaping is probably not the cause). Do you maybe have a non-standard IFS environment variable?