简体   繁体   English

如何每隔X一次运行脚本删除文件-从脚本内部管理日志文件?

[英]How To Delete A File Every X Times A Script Is Run - Manage A Log File From Inside A Script?

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. 我通常将其安排为cron作业或脚本,但是,我只想在50次之后删除日志文件(每次脚本运行时都会不断添加到该日志文件中)。

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. 然后,如果该值大于X,则删除文件。 That portion of the code would be a grep or awk statement. 该部分代码将是grepawk语句。

Anyone know an easy, better way to do this? 任何人都知道一种简单,更好的方法吗? Your positive input is highly appreciated. 非常感谢您的积极投入。

You could use xattr to associate arbitrary metadata with a file, like this: 您可以使用xattr将任意元数据与文件关联,如下所示:

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. 这样做的好处是,它不会在grep显示,也不会在使用常规工具查看文件时显示。

Note that not all filesystems (eg Microsoft FAT) will support xattr . 请注意,并非所有文件系统(例如Microsoft FAT)都将支持xattr

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: 由于Gnu awk v.4.1可以使用就地编辑(请参见awk将修改保存到位 ),因此,您可以将计数器存储到awk脚本变量中,并使用awk脚本进行自我编辑并像这样递减计数器变量:

$ 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. 基本上你运行program.awk改变一个记录program.awk就地,一旦反命中0时, if得到执行。

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 . 在下面的代码中使用sed ,它将在脚本中使x每次递增1 ,每次运行脚本时最多递增50 ,然后将x设置回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. 您可以将命令设置为处理if 语句else分支中的日志文件 ,以及要在每个分支中运行的其他任何代码

#!/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: 在这里,我运行脚本以显示x递增,并在运行50次后重置为1

$ 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 . 如您所见, 脚本中 x=1变成了x=2

I now manually set x=2 to x=50 and saved the script to show it resets to x=1 . 现在,我手动将x=2设置为x=50并保存了脚本,以显示它重置为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
$ 

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. 如@EvansWinner所述,我可以使用文件大小或年龄等属性来管理文件。 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. 希望对于试图在脚本中每x删除一次文件的人,这将帮助您查看文件属性以及如何使用大小,使用年限或我使用的行数来管理文件属性。 These solutions are much more portable than creating programs or packages that are required on other systems. 与创建其他系统所需的程序或软件包相比,这些解决方案具有更大的可移植性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM