1 # $Id: ShellQuote.pm,v 1.11 2010-06-11 20:08:57 roderick Exp $
 
   3 # Copyright (c) 1997 Roderick Schertler.  All rights reserved.  This
 
   4 # program is free software; you can redistribute it and/or modify it
 
   5 # under the same terms as Perl itself.
 
   9 String::ShellQuote - quote strings for passing through the shell
 
  13     $string = shell_quote @list;
 
  14     $string = shell_quote_best_effort @list;
 
  15     $string = shell_comment_quote $string;
 
  19 This module contains some functions which are useful for quoting strings
 
  20 which are going to pass through the shell or a shell-like object.
 
  26 package String::ShellQuote;
 
  29 use vars qw($VERSION @ISA @EXPORT);
 
  35 @EXPORT     = qw(shell_quote shell_quote_best_effort shell_comment_quote);
 
  42 sub _shell_quote_backend {
 
  48   print RS::Handy::data_dump(\@in);
 
  51     return \@err, '' unless @in;
 
  54     my $saw_non_equal = 0;
 
  56   if (!defined $_ or $_ eq '') {
 
  62       push @err, "No way to quote string containing null (\\000) bytes";
 
  67   # = needs quoting when it's the first element (or part of a
 
  68   # series of such elements), as in command position it's a
 
  69   # program-local environment setting
 
  72       if (!$saw_non_equal) {
 
  80   if (m|[^\w!%+,\-./:=@^]|) {
 
  85     || (!$saw_non_equal && /=/)) {
 
  90       # make multiple ' in a row look simpler
 
  91       # '\'''\'''\'' -> '"'''"'
 
  92           s|((?:'\\''){2,})|q{'"} . (q{'} x (length($1) / 4)) . q{"'}|ge;
 
 107 =item B<shell_quote> [I<string>]...
 
 109 B<shell_quote> quotes strings so they can be passed through the shell.
 
 110 Each I<string> is quoted so that the shell will pass it along as a
 
 111 single argument and without further interpretation.  If no I<string>s
 
 112 are given an empty string is returned.
 
 114 If any I<string> can't be safely quoted B<shell_quote> will B<croak>.
 
 119     my ($rerr, $s) = _shell_quote_backend @_;
 
 123       @$rerr = grep { !$seen{$_}++ } @$rerr;
 
 124   my $s = join '', map { "shell_quote(): $_\n" } @$rerr;
 
 131 =item B<shell_quote_best_effort> [I<string>]...
 
 133 This is like B<shell_quote>, excpet if the string can't be safely quoted
 
 134 it does the best it can and returns the result, instead of dying.
 
 138 sub shell_quote_best_effort {
 
 139     my ($rerr, $s) = _shell_quote_backend @_;
 
 144 =item B<shell_comment_quote> [I<string>]
 
 146 B<shell_comment_quote> quotes the I<string> so that it can safely be
 
 147 included in a shell-style comment (the current algorithm is that a sharp
 
 148 character is placed after any newlines in the string).
 
 150 This routine might be changed to accept multiple I<string> arguments
 
 151 in the future.  I haven't done this yet because I'm not sure if the
 
 152 I<string>s should be joined with blanks ($") or nothing ($,).  Cast
 
 153 your vote today!  Be sure to justify your answer.
 
 157 sub shell_comment_quote {
 
 160   croak "Too many arguments to shell_comment_quote "
 
 161             . "(got " . @_ . " expected 1)";
 
 176     $cmd = 'fuser 2>/dev/null ' . shell_quote @files;
 
 177     @pids = split ' ', `$cmd`;
 
 179     print CFG "# Configured by: ",
 
 180     shell_comment_quote($ENV{LOGNAME}), "\n";
 
 184 Only Bourne shell quoting is supported.  I'd like to add other shells
 
 185 (particularly cmd.exe), but I'm not familiar with them.  It would be a
 
 186 big help if somebody supplied the details.
 
 190 Roderick Schertler <F<roderick@argon.org>>