$pic is being incremented. This however has absolutely no effect on $key_MS which was set and evaluated when $pic was still 1. If you want to have it re-evaluated every time it is referenced you would need a closure or an eval or similar. eg. (with the loop replaced for clarity)
#!/usr/bin/env perl
use strict;
use warnings;
my $pic = 1;
my $key_MS = sub { "R3R3_${pic}_IF"; };
print "Old pic value is " . &$key_MS . "\n";
$pic = 2;
print "New pic value is " . &$key_MS . "\n";
| [reply] [d/l] [select] |
my $key_MS = sub { "R3R3_${pic}_IF"; };
print "set service-interface $v->{&$key_MS}.0\n";
| [reply] [d/l] |
Works for me. But when in doubt, use the . concat operator, like in the second example below, or in the case of print, the comma operator like in the third example. Otherwise, please be more specific than "it may not work", and provide a piece of example code where it fails (see How do I post a question effectively?).
my $v = { R3R3_1_IF=>"xx", R3R3_2_IF=>"yy", R3R3_3_IF=>"zz" };
my $pic = 1;
my $key_MS = sub { "R3R3_${pic}_IF"; };
print "set service-interface $v->{&$key_MS}.0\n";
$pic++;
print "set service-interface " . $v->{&$key_MS} . ".0\n";
$pic++;
print "set service-interface ", $v->{&$key_MS}, ".0\n";
__END__
set service-interface xx.0
set service-interface yy.0
set service-interface zz.0
| [reply] [d/l] [select] |