1

I would normally just schedule this as a cron job or script, however, I would like to delete a log file (it's constantly appended to every time a script runs) only after 50 times.

Needed Inside The Script:

The thing is, since the script does not run consistently, it has be to be implemented within the script itself. Please note: for various reasons, I need this inside the script.

What I Was Trying:

I was thinking of setting a variable to increment, outputting it to a file and then having the script read that file every time. Then, if that value is greater than X, remove the file. That portion of the code would be a grep or awk statement.

Anyone know an easy, better way to do this? Your positive input is highly appreciated.

DomainsFeatured
  • 1,426
  • 1
  • 21
  • 39
  • One possibility is to use `cron` itself to store the counter. Have your script take a numeric argument. Instead of schedule a recurring `cron` job, have the script itself schedule its next run (with an incremented or reset argument) via `cron` or just `at`. – chepner Nov 01 '16 at 18:46
  • 2
    Dealing with log files getting too large is a solved problem. Perhaps you would like to try `logrotate` ? http://www.linuxcommand.org/man_pages/logrotate8.html – xxfelixxx Nov 01 '16 at 18:51
  • Do you need to delete the log file to keep it from getting too big? Could you just check the size of the log file on every run and delete it if it is over a given size, whether on the 50th time or the 1st? Similarly, if you run this job regularly, could you just check the age of the log file? – EvansWinner Nov 01 '16 at 19:12
  • Hey @EvansWinner, yes! You are correct. That would work beautifully, preferably by age so we can specify by time. If you would like to provide the code as an answer, I would be happy to accept it. Please upvote the question if you liked it too. Thanks so much. – DomainsFeatured Nov 01 '16 at 19:15

4 Answers4

2

You could use xattr to associate arbitrary metadata with a file, like this:

touch a.txt                # Create file
xattr -w runs 1 a.txt      # Set run count to 1
xattr -p runs a.txt        # Print run count
1

xattr -w runs 49 a.txt     # Change value
xattr -l a.txt             # List all attributes
runs: 49

The beauty of that is it doesn't show up in grep or when looking at the file with normal tools.

Note that not all filesystems (e.g. Microsoft FAT) will support xattr.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
2

Since the Gnu awk v.4.1 the inplace edit has been available (see awk save modifications in place) so, you could store the counter to your awk script variable and use the awk script to edit itself and decrement the counter varible like this:

$ cat program.awk
BEGIN {
    this=5                                  # the counter variable
}
/this=[0-9]+/ {                             # if counter (this=5) matches
    if(this==0)                             # if counter is down to 0...
        ;                                   # ... do what you need to do
    split($0,a,"=")                         # split "this=5" by the "="
    sub(/=[0-9]+$/,"=" (a[2]==0?5:a[2]-1))  # decrement it or if 0 set to 5 again
}
1                                           # print

Run it:

$ awk -i inplace -f program.awk program.awk
$ head -3 program.awk
BEGIN {
    this=4                                  # the counter variable
}

Basically you run program.awk that changes one record in program.awk inplace and once counter hits 0, the if gets executed.

Community
  • 1
  • 1
James Brown
  • 36,089
  • 7
  • 43
  • 59
1

Using sed in the code below it will increment x by 1 within the script, each time the script is run, up to 50 and then set x back to 1. You can set the command to process the logfile in the else branch of the if statement along with whatever other code you want to run in each branch.

#!/bin/bash

x=1
y=$((x+1))
z=1

if [ $x -lt 50 ]; then
    # Do something...

    sed -i -e "s/x=$x/x=$y/" "$0"
else
    # Do something...
    # Delete logfile...

    sed -i -e "s/x=$x/x=$z/" "$0"
fi

Here I run the script to show x gets incremented and reset back to 1 after 50 runs:

$ cat testscript
#!/bin/bash

x=1
y=$((x+1))
z=1

if [ $x -lt 50 ]; then
    # Do something...

    sed -i -e "s/x=$x/x=$y/" "$0"
else
    # Do something...
    # Delete logfile...

    sed -i -e "s/x=$x/x=$z/" "$0"
fi
$ ./testscript
$ cat testscript
#!/bin/bash

x=2
y=$((x+1))
z=1

if [ $x -lt 50 ]; then
    # Do something...

    sed -i -e "s/x=$x/x=$y/" "$0"
else
    # Do something...
    # Delete logfile...

    sed -i -e "s/x=$x/x=$z/" "$0"
fi
$

As you can see x=1 has became x=2 within the script.

I now manually set x=2 to x=50 and saved the script to show it resets to x=1.

$ cat testscript
#!/bin/bash

x=50
y=$((x+1))
z=1

if [ $x -lt 50 ]; then
    # Do something...

    sed -i -e "s/x=$x/x=$y/" "$0"
else
    # Do something...
    # Delete logfile...

    sed -i -e "s/x=$x/x=$z/" "$0"
fi
$ ./testscript
$ cat testscript
#!/bin/bash

x=1
y=$((x+1))
z=1

if [ $x -lt 50 ]; then
    # Do something...

    sed -i -e "s/x=$x/x=$y/" "$0"
else
    # Do something...
    # Delete logfile...

    sed -i -e "s/x=$x/x=$z/" "$0"
fi
$ 
user3439894
  • 7,266
  • 3
  • 17
  • 28
0

As mentioned, my main requirement is to do this inside the script or in-line. As @EvansWinner mentioned, I can manage the file by using properties like the file size or age. However, I went with something even more simple, using number of lines.

sed -i '100000,$ d' file.txt

Thus, I don't have to worry about how many times it runs. Hopefully, for anyone who is trying to also delete a file every x times, within a script, this will help you look at the file properties and how they can be managed using size, age or as I have used, number of lines. These solutions are much more portable than creating programs or packages that are required on other systems.

DomainsFeatured
  • 1,426
  • 1
  • 21
  • 39