LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   handling perl string containing '@' and '$' with system function (https://www.linuxquestions.org/questions/programming-9/handling-perl-string-containing-%40-and-%24-with-system-function-602834/)

powah 11-27-2007 05:24 PM

handling perl string containing '@' and '$' with system function
 
If I had a perl string $newpw containing '@' and '$', (e.g. "5a@Wf7$X") how to pass it to the system function properly?
This does not work:
system("/usr/local/bin/acthw -pw \"$newpw\"");

chrism01 11-27-2007 06:25 PM

Escape like this

var1="5a\@Wf7\$X";
system("echo $var1");

powah 11-27-2007 07:47 PM

Quote:

Originally Posted by chrism01 (Post 2972701)
Escape like this

var1="5a\@Wf7\$X";
system("echo $var1");

Your solution requires that I know the string in advance.
Is there a solution which allow an arbitrary string inputed by a user?

chrism01 11-27-2007 08:33 PM

This works for me:

$var1 = 'asd@fgh$hjk';
print "$var1\n";
system("echo \'$var1\' ");


output:
asd@fgh$hjk
asd@fgh$hjk

you need to enforce single quotes to prevent un-needed interpolation.

sundialsvcs 11-27-2007 08:51 PM

"Interpolation and escaping" can become the sort of issues that cause a seasoned programmer to look at you with an expression that vaguely resembles table-tennis, because in her (or his) own mind that's rather-exactly what's going on at the time.

If you have a literal string with "magical" characters in it, such as 5a@Wf7$X, then your Perl program needs to change that string into a character sequence that the shell program, upon receiving it, will change back into the original!

(Take a moment to let the "ping-pong look" come and go...) ;)

So what you need to do is to take a string that looks like this...

5a@Wf7$X

... and make it look like this...

5a\@Wf7\$X

... so that the shell-program you wish to run can change it back to the original ...

5a@Wf7$X

(Actually, the shell itself performs this service...)

So, what you need to do is to "escape" the string that you've been given so that the shell can then "un-escape" it back into the original string.

Something like this extemporaneously-written bit of chicken-scratching might do it:

$foo =~ s/[@$\]/\\\1/g; (ooh, ick!) might do it...

Let me try to explain...
  1. The syntax $foo =~ regexp applies a regular-expression against the variable $foo.
  2. The regular-expression is of the form s/change_from/change_to/globally...
  3. The change_from part is "either of the two characters '@' or '$' or '\'"
  4. The change_to part is 'a literal backslash character' followed by 'whatever character you found.'

If you are extremely lucky, you will happily find that this regular-expression transforms your string consistently into a string that will eventually be transformed back to the original string.

Fun stuff, huh?

chrism01 11-27-2007 11:30 PM

Yeah I started by trying something like that, but coudln't get the esc/unesc seq to perform correctly for the $ under use strict & -w, so went for single quotes eventually.
I'm sure these guys here (www.perlmonks.org) could come up with a version that does work. If you do go there, please post the answer, as I'd be glad to see it.

theNbomr 11-29-2007 06:55 PM

Then there's the good old 'quotemeta' function:
Code:

#! /usr/bin/perl -w

# LQpowah.pl    quotemeta demo
#
#  Usage:  LQpowah.pl file_with_metachar_strings

use strict;
    while( <> ){
        my $quotedString = quotemeta( $_  );
        print $quotedString, "\n";
    }

Code:

LQpowah.pl
5a@Wf7$X
5a\@Wf7\$X\

--- rod.

chrism01 11-30-2007 12:54 AM

For me, it wasn't so much the perl print, that was fine, it was passing it out to system and still getting a 'clean/complete' string for the receiving prog.


All times are GMT -5. The time now is 02:45 AM.