http://qs321.pair.com?node_id=67929

ftforger has asked for the wisdom of the Perl Monks concerning the following question:

I have a script something like this (I know this doesn't work, this is just a rough sample)

$v1="user_value1"; open(INFILE,"<template.file"); $input=<INFILE>; eval $input; $line = "$input"; close(INFILE); print "$line\n";

with the contents of "template.file" being

thing1 type1 $v1

What I want is when the script runs, the print would produce:

thing1 type1 user_value1

Replies are listed 'Best First'.
Re: "eval" variable in non-perl statment?
by stephen (Priest) on Mar 29, 2001 at 00:30 UTC
      Thank you very much. Thats pretty much what I was looking for. I knew it existed, I just couldn't find it...
Re: "eval" variable in non-perl statment?
by athomason (Curate) on Mar 29, 2001 at 00:38 UTC
    Superior methods exist for what you want to do (see other posts and the caveat at the end of this one), but the fix for what you have is simple. You need perl to consider your $input as a string to get it to interpolate. This code should work for you:
    use strict; my $v1="user_value1"; open(INFILE,"<template.file") or die "Couldn't open file: $!"; my $input=<INFILE>; close(INFILE); $input = '"' . $input . '"';; my $line = eval $input; print "$line\n";
    Depending on your desired output, you might also want to chomp off the newline that comes with $input

    Also, be exceedingly careful with how you use this. You typically shouldn't eval anything passed from the user, as you're possibly introducing an enormous security headache. String eval on user data is frequently an open invitation for the user to execute code of their choice. I'd sleep easier at night using the s/// operator to fill in the values if that's an option. If you can't do that for whatever reason, use taint checking and thoroughly consider how your script could be abused.

      Thanks, and I understand the security issues here. Its not really a case of evaling what the user has input as it is just expanding a variable in a template context. We will probably use the Text::Template module. The template file is to be kept inside of a configuration managed directory with controlled access, so it would be pretty hard to put something damaging in there, and the perp would leave tracks in the config management system.
Re: "eval" variable in non-perl statment?
by mr.nick (Chaplain) on Mar 29, 2001 at 00:35 UTC
Re: "eval" variable in non-perl statment?
by c-era (Curate) on Mar 29, 2001 at 00:32 UTC
    You should used a module (like the template toolkit), but for something really simple (or for fun), you can use a regex: $input =~ s/(\$.*?) /eval ("\$tmp = $1;"); "$tmp "/e; Note, this code is easy to break, you can't have any other $, and you need to be careful about line breaks.