Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
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 perusing the Monastery: (5)
As of 2014-11-27 21:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (188 votes), past polls