Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Mimicking Unix shell quoting in Perl

by eyepopslikeamosquito (Chancellor)
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,, 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 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 However, this feels quite tricky and I've got that old re-inventing the wheel feeling. Is there a better way to do this?

Replies are listed 'Best First'.
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 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 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;
Re: Mimicking Unix shell quoting in Perl
by djerius (Beadle) on Aug 20, 2007 at 14:48 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://633728]
Approved by Corion
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (1)
As of 2018-01-17 19:16 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (203 votes). Check out past polls.