Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Mimicking Unix shell quoting in Perl

by eyepopslikeamosquito (Canon)
on Aug 20, 2007 at 07:33 UTC ( #633728=perlquestion: print w/ replies, xml ) Need Help??
eyepopslikeamosquito has asked for the wisdom of the Perl Monks concerning the following question:

I'd like to be able to mimic the way the Unix shell tokenizes a command line into what a Perl program sees as @ARGV. This little test program hopefully makes clear what I'd like to achieve:

# Mimic the way the Unix shell breaks up cmdline into @ARGV. # Before running this script, create a separate test script, g.pl, con +sisting of: # for my $a (@ARGV) { print "a=:$a:\n" } use strict; use warnings; ### $qq matches a single or double quoted string. my $qq = qr/'[^'\\]*(?:\\.[^'\\]*)*'|"[^"\\]*(?:\\.[^"\\]*)*"/; my $cmd = qq{perl g.pl arg1 'arg 2' "arg 3" "arg \\"4" arg5}; print "cmd=:$cmd:\n\n"; my @args = $cmd =~ /$qq|\S+/g; for my $t (@args) { if (substr($t, 0, 1) eq "'" || substr($t, 0, 1) eq '"') { $t = substr($t, 1, -1); $t =~ s/\\(['"])/$1/g; } } for my $a (@args) { print "a=:$a:\n" } print "\n"; system($cmd); print "\n"; system { $^X } @args;
Running this program shows that @args above matches what is seen as @ARGV in g.pl. However, this feels quite tricky and I've got that old re-inventing the wheel feeling. Is there a better way to do this?

Comment on Mimicking Unix shell quoting in Perl
Select or Download Code
Re: Mimicking Unix shell quoting in Perl
by Anonymous Monk on Aug 20, 2007 at 08:04 UTC
      Looking at Shell::Parser leaves me empty inside. It looks like a very lightweight wrapper around lexical analysis. It doesn't appear to do any glob syntax expansion like eyepopslikeamosquito wanted.

      Not only does bash globbing syntax handle foo*.jpg but it deals with foo?.jpg and foo[1-5][xyz].jpg and even foo.{jpg,jpeg} options too. It's a pretty complicated feature, even if you skip all the $VAR interpolation stuff.

      Speaking of which, eyepopslikeamosquito, is it important for your purposes to do things exactly like the shell? Can you assume you're on a platform that actually has the shell, or must you work smoothly on Win/DOS too? You could just shell out a string to xargs, but this is a significant taint-checking exercise too.

      --
      [ e d @ h a l l e y . c c ]

        The Windows shell doesn't do glob. So even a module that doesn't handle globbing can still be much like a "real shell". It just depends on what you use as a role model. :)
Re: Mimicking Unix shell quoting in Perl
by djerius (Beadle) on Aug 20, 2007 at 14:48 UTC
Re: Mimicking Unix shell quoting in Perl
by brx (Pilgrim) on Aug 20, 2007 at 15:39 UTC
    Text::Balanced can probably help you
    use strict; use warnings; use Text::Balanced qw(extract_delimited); my $cmd = qq{perl g.pl arg1 'arg 2' "arg 3" "arg \\"4" arg5}; my @tokens; while(length($cmd)){ my $ext = extract_delimited($cmd); if (not defined $ext) { $cmd=~s/^\s*(\S+)\s*//; $ext=$1; } else { ####no delimiters # $ext=substr($ext,1,-1); } push @tokens,$ext; } print join "\n",@tokens;

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://633728]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (3)
As of 2014-09-23 03:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (210 votes), past polls