Perl script to set IP settings
There's no need to predeclare the subs (sub whatever;).
There's no need to assign the initial values to %resulthash.
my $filename; does the same as my $filename = undef;. There's no need to specify the undef.
Hash keys are autoquoted if they are simple (i.e. follow the same rules as variable name). Instead of $resulthash{'IPADDR'} you can type just $resulthash{IPADDR}.
shift in a sub operates on @_. So you can just write my $hash = shift;.
Instead of shifting @_ several times, assign all the variables at the same time: my ($key, $value) = @_;.


Plus, you're comparing $fields[0] to various strings, maybe a "dispatch table" would be a bit clearer. See my version of the script:

#!/usr/bin/perl
use strict;
use warnings;

use Getopt::Long;
use Tie::File;

my %resulthash;
my $filename;

GetOptions ('filename=s' =&gt; \$filename,
            'IP=s'       =&gt; \$resulthash{IPADDR},
            'NETMASK=s'  =&gt; \$resulthash{NETMASK},
            'GATEWAY=s'  =&gt; \$resulthash{GATEWAY},
            'DNS1=s'     =&gt; \$resulthash{DNS1},
            'DNS2=s'     =&gt; \$resulthash{DNS2})
or die 'Error in input values';

open my $fd, '&gt;&gt;', $filename
    or die "Cannot open file $filename";

tie my @array, 'Tie::File',  $filename
    or die "Cannot tie file '$filename': $!";

for my $line (@array) {
    my @fields = split /=/, $line;

    { BOOTPROTO =&gt; sub { $fields[1] = '"static"';
                         $line = join '=', @fields; },
      IPADDR    =&gt; sub { $line = setValueForField('IPADDR', @fields); },
      NETMASK   =&gt; sub { $line = setValueForField('NETMASK', @fields); },
      GATEWAY   =&gt; sub { $line = setValueForField('GATEWAY', @fields); },
      DNS1      =&gt; sub { $line = setValueForField('DNS1', @fields); },
      DNS2      =&gt; sub { $line = setValueForField('DNS2', @fields); },
    }-&gt;{ $fields[0] }-&gt;();
}

untie @array;

addMissingValues(\%resulthash);

close $fd;

sub addMissingValues {
    my $hash = shift;

    while (my ($key, $value) = each %$hash) {
        createNewField($key, $value) if defined $value;
    }
}

sub createNewField {
    my ($key, $value) = @_;
    print {$fd} join '=', $key, $value;
    print {$fd} "\n";
}

sub setValueForField {
    my ($fieldname, @fields) = @_;

    $fields[1] = $resulthash{$fieldname};

    return join '=', @fields;
}


You can also keep the dispatch table outside of the loop, but you need to pass parameters to the callbacks.

my %DISPATCH = (
    BOOTPROTO =&gt; sub { $_[1] = '"static"';
                       join '=', @_ },
    IPADDR    =&gt; sub { setValueForField('IPADDR', @_) },
    NETMASK   =&gt; sub { setValueForField('NETMASK', @_) },
    GATEWAY   =&gt; sub { setValueForField('GATEWAY', @_) },
    DNS1      =&gt; sub { setValueForField('DNS1', @_) },
    DNS2      =&gt; sub { setValueForField('DNS2', @_) },
);

for my $line (@array) {
    my @fields = split /=/, $line;
    my $sub = $DISPATCH{ $fields[0] };
    $line = $sub-&gt;( @fields) if $sub;
}