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

Yeah, if preserving the existing file permissions is a goal, spew might change them

There is no need to give append an empty array, its the same as if you didn't give it an array  path( $file )->append({ truncate => 1 });

spew looks much nicer than a truncate option

Another way to is  truncate path( $file )->opena, 0; but that isn't much better than the previous one

Simply clobbering the file works but might not be as clear in intent as spew  path( $file )->openw;

A test

$ perl -MPath::Tiny -le " my $f = path( 2 ); $f->spew(2); print $f->s +lurp; $f->openw; print $f->slurp; " 2

Replies are listed 'Best First'.
Re^5: Clear the contents of the text file
by 1nickt (Canon) on Jul 22, 2015 at 01:46 UTC

    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.

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