in reply to Problem running IPTraf from Perl

Some minor thought. %ENV is a global variable, thus everyone using it will be affected by changing it. Consider deciding whether you'd like to set the environment variable for the whole script, or just for your call to iptraf.

If it should be effective for your whole script set it at the beginning of the script, or some other well exposed place. If for the call to iptraf is sufficient consider localizing the change, like so:

{ local %ENV = %ENV; $ENV{TERM} = 'vt220'; # call iptraf, e.g. `/usr/sbin/iptraf -s eth0 -B -L some.log`; }

This will limit the changes to %ENV to the enclosing block, thus the environment will be restored once the block is left. See Temporary Values via local()

It might be worth remembering this for all global variables.

Replies are listed 'Best First'.
Re^2: Problem running IPTraf from Perl
by RobPayne (Chaplain) on Jun 17, 2006 at 12:20 UTC
    The idea of not changing global variables is a good thought, but, changing $ENV within a perl script does not effect the shell that the script was run from, you can see that by doing:
    $ echo $TERM; perl -e '$ENV{$TERM} = "strange";'; echo $TERM
    This holds true whether you edit the (any) variable from Perl or from another (sub-)shell.

      True, the environment only propagates down the process tree. But any process spawned by the script will see the changed environment, and these changes might be unexpected by other parts of the program. TERM might not be a problem, but others like PATH, LD_PRELOAD, or something else might well be.

      I like to make global changes, not only the environment but every global perl variable, as local as possible.

      print `echo %TERM%`; $ENV{TERM} = 'vt220'; # In some code, far, far away... print `echo %TERM%`;
      C:\tmp>perl t.pl %TERM% vt220
Re^2: Problem running IPTraf from Perl
by Hue-Bond (Priest) on Jun 23, 2006 at 22:20 UTC
    local %ENV = %ENV; $ENV{TERM} = 'vt220';

    No need to localize the entire hash to alter just one value. You can localize single elements of hashes and arrays:

    { local $ENV{TERM} = 'vt220'; `/usr/sbin/iptraf -s eth0 -B -L some.log`; }

    Exiting the block will restore the old contents of the hash or array, making the element reappear if it was deleted:

    my %letters = 'a'..'h'; my @nums = 0..8; { local $letters{'c'}; delete $letters{'c'}; local $nums[4]; @nums = (); } use Data::Dumper; print Data::Dumper->Dump ( [\%letters, \@nums], ['letters', 'nums'] ); __END__ $letters = { 'e' => 'f', 'c' => 'd', 'a' => 'b', 'g' => 'h' }; $nums = [ undef, undef, undef, undef, 4 ];

    This is all documented in perlsub.

    --
    David Serrano