如何使脚本以已执行的次数登录一个单独的文件?

Mil*_*rov 11 command-line bash scripts

我需要编写一个脚本,将这个脚本执行了多少次写入文件。

我怎样才能做到这一点?

Byt*_*der 15

我假设您想要一个countfile只包含一个代表执行计数器的数字的文件。

您可以将此计数器读入 shell 变量,$counter例如使用以下行之一:

可以使用$(( EXPRESSION ))语法在 Bash 本身中完成简单的整数加法。然后只需将结果写回我们的countfile

echo "$(( counter + 1 ))" > countfile
Run Code Online (Sandbox Code Playgroud)

您可能还应该针对countfile尚不存在的情况保护您的脚本,然后创建一个用值 1 初始化的脚本。

整个事情可能是这样的:

#!/bin/bash
if [[ -f countfile ]] ; then
    read counter < countfile
else
    counter=0
fi
echo "$(( counter + 1 ))" > countfile
Run Code Online (Sandbox Code Playgroud)

  • ……或者像这样:`echo $(( $(cat countfile 2&gt;/dev/null || echo 0) + 1 )) &gt; countfile` (2认同)
  • 通过将该计数代码包装在“flock”命令中以防止竞争条件,可以改进此答案。见 https://unix.stackexchange.com/a/409276 (2认同)

Vid*_*uth 5

只需让脚本创建一个日志文件,例如在脚本的末尾添加一行:

echo "Script has been executed at $(date +\%Y-\%m-\%d) $(date +\%H-\%M-\%S)" >> ~/script.log
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以自己格式化显示日期和时间的方式,但是如果您只想使用完整的日期和时间(并且HH:MM:SS是您可以接受的格式),您也可以简单地使用:

echo "Script has been executed at $(date +\%F-\%T)" >> ~/script.log
Run Code Online (Sandbox Code Playgroud)

那么你可以这样做:

wc -l ~/script.log
Run Code Online (Sandbox Code Playgroud)

它计算换行符并估计日志文件中有多少行。到目前为止,您可以在日志文件中看到,即使它被执行。为了适应您的需要,您可以更改用于日志记录的路径和名称。我只是在这里做了一个例子,它将日志文件保存在~.

因此,例如,您希望脚本将此计数添加到您在脚本末尾添加的行中,您可以在脚本开头执行以下操作:

count=$(( $(wc -l ~/script.log | awk '{print $1}') + 1 ))
# the next line can be simply skipped if you not want an output to std_out
echo "Script execution number: $count"
Run Code Online (Sandbox Code Playgroud)

并将脚本末尾的行更改为包括该信息的内容:

echo "Script has been executed $count times at $(date +\%F-\%T)" >> ~/script.log
Run Code Online (Sandbox Code Playgroud)


Dav*_*ter 5

此解决方案使用与Byte Commander 的答案相同的方法,但它不依赖于 shell 算法或其他 Bashisms。

exec 2>&3 2>/dev/null
read counter < counter.txt || counter=0
exec 3>&2 3>&-
expr "$counter" + 1 > counter.txt
Run Code Online (Sandbox Code Playgroud)

流重定向

  1. 将标准错误流 (2) 复制到不同的文件描述符 (3),
  2. 将它 (2) 替换为重定向到/dev/nullread如果计数器文件预期丢失,则在命令输入的后续重定向中抑制错误消息),
  3. 稍后将原始标准错误流(现在为 3)复制回原位 (2) 和
  4. 关闭标准错误流的副本 (3)。