in reply to Re^4: Clear the contents of the text file
in thread Clear the contents of the text file

There is no need to give append an empty array

Not true according to testing:

[18:45][nick:~/monks]$ cat test.dat foo bar baz quux [18:45][nick:~/monks]$ cat 1135741.pl #! perl -w use strict; use feature qw/ say /; use Path::Tiny qw/ path /; my $file = 'test.dat'; my @lines = path( $file )->lines( { chomp => 1 } ); #my @append = (); # empty array path( $file )->append( '', { truncate => 1 } ); say "Done."; __END__ [18:45][nick:~/monks]$ perl !$ perl 1135741.pl Done. [18:45][nick:~/monks]$ cat test.dat foo bar baz quux HASH(0x7fa310898690)
The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^6: Clear the contents of the text file
by Anonymous Monk on Jul 22, 2015 at 03:02 UTC

    There is no need to give append an empty array

    1nickt: Not true according to testing:

    When you give a function/method/sub an empty array as an argument, what do you think that sub gets/receives in the parameter list? Its nothing.

    $ perl -le" sub f { print scalar @_ }; f(1,2); f( @ARGV ); " 2 0 $ perl -le" sub f { print scalar @_ }; f(1,2); f( @ARGV ); " a b c 2 3

    Your test is not a self contained test

    You also seems to be dealing with some kind of shell

    It really doesn't show what you think it shows

    #!/usr/bin/perl -- use strict; use warnings; use Data::Dump qw/ dd /; use Path::Tiny qw/ path /; my $goner = path( 'goner' ); $goner->spew("1\n\2\n\3\n"); dd( $goner->slurp_raw ); $goner->append( { truncate => 1 } ); dd( $goner->slurp_raw ); $goner->remove; __END__ "1\r\n\2\r\n\3\r\n" ""

      You can't have a "self-contained test" if you are testing writing to a file. You need to write to the file. The shell commands showed the output of cat. The test showed exactly what the output indicated:

      If you pass append() an empty string, as shown in the spew() example I was replying to, you will get an error.

      And the reason to do this in the OP's case is not for file permission preservation, but for file locking.

      The way forward always starts with a minimal test.

        You can't have a "self-contained test" if you are testing writing to a file. You need to write to the file. The shell commands showed the output of cat. The test showed exactly what the output indicated: If you pass append() an empty string, as shown in the spew() example I was replying to, you will get an error.

        Who suggested passing an empty string as in the spew example?

        That is the wrong way to try to use path()->append

        And the reason to do this in the OP's case is not for file permission preservation, but for file locking.

        The rest of the OPs program doesn't use advisory locking, so there is no benefit if Path::Tiny uses it

        Therefore there is no benefit to using append at all

Re^6: Clear the contents of the text file
by shroh (Acolyte) on Jul 22, 2015 at 02:06 UTC
    Hi lnickt, I am getting the error here: E:\Temp\inyrohs>perl outage_nodes_updated.pl on Can't locate Path/Tiny.pm in @INC (@INC contains: E:/apps/Perl64/site/lib E:/apps/Perl64/lib .) at outage_nodes_updated.pl line 8. BEGIN failed--compilation aborted at outage_nodes_updated.pl line 8.
    #!C:\Perl\bin\perl.exe use Win32; use IO::Handle; use File::Find; use strict; use warnings; use File::Copy qw(copy); use Path::Tiny qw/ path /; use feature qw/ say /; ###################################################################### +############## #This script is created to put the servers in unplanned outage as part + of the tasks# #that are received to stop the monitoring on the servers #due to some maintenance activity on the servers. # # # require "E:/Temp/inyrohs/omwNodeDetails.pm"; #expect values 'on|off' my ($SEC,$MIN,$HOUR, $DAY, $MON, $YEAR)= (localtime) [0..6]; my $year=$YEAR+1900; my $month=$MON+1; my $day=$DAY; my $date="$year\_$month\_$day"; my $LOG="E:/Temp/inyrohs/maintenanceMode_$date.log"; my $serverlist="E:/Temp/INYROHS/serverlist.txt"; open( MYFILE, "E:/Temp/INYROHS/serverlist.txt") or die "Can't open '$ +serverlist': $!"; my @outagenodes=path($MYFILE)->lines({chomp => 1}); #chomp(@outagenodes); #print "@outagenodes\n"; my $maintMode=$ARGV[0]; chomp($maintMode); open (LOG,">> $LOG") or die "Can't open $LOG file: $!\n"; printf LOG ("\nTime is %02d:%02d:%02d.\nStarting the maintenance mode +process to turn $maintMode outages.\n\n", $HOUR, $MIN, $SEC); #print "$date \n"; #print "starting the process \n"; #print "maintMode: $maintMode:\n"; while (<$MYFILE>){ s/\s+$//; s/^\s+//; next if /^$/; if($maintMode =~ m/on/) { foreach my $NODES (@outagenodes) { my @parts=split /\./, $NODES; my $hostname=$parts[0]; chomp($hostname); my $fqdn = getNodeAttributes($hostname,"PrimaryNodeName"); print "$hostname\n"; #printLog("Node: $NODES, processing...\n"); #print "entered loop \n"; my $cmd="ovownodeutil.cmd -outage_node -unplanned -disable_ +heartbeat -delete_msgs -node_name $fqdn -$maintMode "; print "$cmd\n"; `$cmd`; print "done with command\n"; } } elsif($maintMode=~ m/off/) { foreach my $NODES (@outagenodes) { my @parts=split /\./, $NODES; my $hostname=$parts[0]; chomp($hostname); my $fqdn = getNodeAttributes($hostname,"PrimaryNodeName"); print "$hostname\n"; printLog("Node: $NODES, processing...\n"); printLog("Bringing the server $NODES out of outage.\n"); my $cmd="ovownodeutil.cmd -outage_node -unplanned -disable_ +heartbeat -delete_msgs -node_name $fqdn -$maintMode"; my $cmdresopcmona="ovdeploy -cmd \"ovc -restart opcmona\" - +host $fqdn"; my $cmdresopcle="ovdeploy -cmd \"ovc -restart opcle\" -host + $fqdn"; print "$cmd\n"; `$cmd`; print "$cmdresopcmona\n"; `$cmdresopcmona`; print "$cmdresopcle\n"; `$cmdresopcle`; } } } my @append=(); path($file)->append(@append, {truncate =>1}); say "Done."; sub printLog { my ($logLine) = @_; chomp($logLine); $logLine=$logLine . "\n"; print "$logLine"; print LOG "$logLine"; }

      You were already given the answer. You get that error because you don't have the Path::Tiny module installed.

      Note that you do not need Path::Tiny, or any module, to read in the lines from a file, or to "clear the contents of the file." You can do it without additional modules, including by using Perl's built-int truncate function, as roboticus told you in the first response to your question.

      The way forward always starts with a minimal test.

      Your indentation makes the code difficult to read but it looks like you are iterating through @outagenodes for each line in the serverlist. I don't think that is what you want. Here's a cleaned up version of your code with some added error checks and logging. Uncomment the commands when you are finished testing.

      poj
        Hi Poj, Thanks a lot for the refined code, It looks prettier. Just need to know the purpose of the below part of the code. But your code is working very well.
        my @nodes = (); while (<SRV>){ # skip blank lines s/\s+$//; s/^\s+//; next if /^$/; # validate records if (/.+/){ # change to suit push @nodes,$_; } else { printLog("ERROR Invalid record '$_'"); } }