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

I get the following error when trying to run IPTraf using the system command or backticks: "Your TERM variable is not set. Please set it to an appropriate value." How does one set the TERM variable for a Perl script?
/usr/sbin/iptraf -s eth0 -B -L some.log
Thanks

Replies are listed 'Best First'.
Re: Problem running IPTraf from Perl
by gellyfish (Monsignor) on Jun 17, 2006 at 07:40 UTC

    The entire environment is available through the %ENV hash, so to set the TERM environment variable you would do:

    $ENV{TERM} = 'vt220';
    obviously substituting the appropriate value.

    /J\

Re: Problem running IPTraf from Perl
by rblasch (Monk) on Jun 17, 2006 at 10:58 UTC

    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.

      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
      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

Re: Problem running IPTraf from Perl
by freakingwildchild (Scribe) on Jun 17, 2006 at 19:50 UTC
    Why not using a small shell script as wrapper around perl, it will keep the environment setting local (if not using mod_perl I presume)...
    #!/bin/bash # export set term="vt120" /usr/sbin/iptraf -s eth0 -B -L some.log