Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't perl inplace editing work if I read user input before that?

I am trying to edit a cfg file inplace inside a perl script, but it doesn't work if I read user input before that. Here is a test script to recreate the problem I am seeing.

#!/usr/bin/perl -w

use strict;

my $TRACE_CFG = "trace.cfg";

print "Continue [y/N]> ";
my $continue = <>;

{
    local $^I = '.bak';
    local @ARGV = ($TRACE_CFG);

    while (<>) {
        s/search/replace/;
        print;
    }

    unlink("$TRACE_CFG.bak");
}

The edit works if I comment out the "my $continue = <>;" line. If I do read user input, it looks like setting @ARGV to trace.cfg file doesn't take effect and the while loop waits for input from STDIN. I can work around this by using sed or using a temporary file and renaming it, but I would like to know the reason for this behaviour and the correct way to do this.

like image 299
pkamala Avatar asked Dec 26 '22 09:12

pkamala


2 Answers

Try,

my $continue = <STDIN>;

instead of

my $continue = <>;

as <> has magic which opens - file handle, and does not look later on what is in @ARGV, thus not processing your files.

like image 144
mpapec Avatar answered Jan 18 '23 23:01

mpapec


According to perlop:

Input from <> comes either from standard input, or from each file listed on the command line. Here's how it works: the first time <> is evaluated, the @ARGV array is checked, and if it is empty, $ARGV[0] is set to "-", which when opened gives you standard input. The @ARGV array is then processed as a list of filenames.

You can modify @ARGV before the first <> as long as the array ends up containing the list of filenames you really want.

like image 38
Lee Duhem Avatar answered Jan 19 '23 01:01

Lee Duhem