Bash script for log rotation Okay, first things first:
Yes, I am aware of the logrotate tool, which would usually be used for something like this.
However, since the logfile i want to rotate already contains a timestamp in the filename, logrotate will never delete old logs.
This script is supposed to:

tell the application to create a new logfile (via SIGHUP)
find all existing, unprocessed logfiles of the application
compress all logfiles except the one currently in use by the application
keep the most recent 7 logs and delete the rest.

From what I can tell, everything seems to work just fine, but I'm curious if anything could be improved.
#!/usr/bin/bash

procname=&quot;foo&quot;
srcpath=&quot;/var/log&quot;
srcname=&quot;*${procname}.log&quot;  # example: 2021-02-05_1200_foo.log
count=7

echo &quot;rotate $procname logs: ${srcpath}/${srcname} ($count rotations)&quot;

pid=&quot;$(pidof $procname)&quot;
if [[ ! $? == 0 ]]
then
    # don't rotate anything if the application is not running
    echo &quot;$procname process not running&quot;
    exit 1
fi

# ask the application to create a new logfile
kill -HUP &quot;$pid&quot;

sleep 1 #probably not necessary?

# get array of all logfiles (should be exactly 2 in most cases)
mapfile -t list &lt;  &lt;(find &quot;$srcpath&quot; -maxdepth 1 -name &quot;$srcname&quot; | sort)
size=${#list[@]}

# don't do anything unless there are at least 2 files
if [[ $size -lt 2 ]]
then
    echo &quot;nothing to do&quot;
    exit 0
fi

# find the active logfile (should be the last one) and delete it from the array
for ((i=size-1; i&gt;=0; i--));
do
    if [[ $(find -L /proc/&quot;$pid&quot;/fd -inum &quot;$(stat -c '%i' &quot;${list[i]}&quot;)&quot;) ]]
    then
        unset &quot;list[i]&quot;
        break
    fi
done

# compress all remaining files (usually just one)
gzip &quot;${list[@]}&quot;

unset list
unset size

# get array of all compressed logfiles
mapfile -t list &lt;  &lt;(find &quot;$srcpath&quot; -maxdepth 1 -name &quot;$srcname.gz&quot; | sort)
size=${#list[@]}

if [[ $size -gt $count ]]
then
    idx=(&quot;${!list[@]}&quot;)
    # remove $count most recent files from $list
    for i in &quot;${idx[@]: -$count:$count}&quot;
    do
        unset &quot;list[$i]&quot;
    done

    # delete the remaining old files
    rm -f &quot;${list[@]}&quot;
fi

exit 0
Shellcheck points out this one:

pid=&quot;$(pidof $procname)&quot;
if [[ ! $? == 0 ]]
then


We can write that more clearly
if ! pid=&quot;$(pidof $procname)&quot;
then

Shortly after that is:

# don't rotate anything if the application is not running
echo &quot;$procname process not running&quot;


That looks like an error message - redirect that to &amp;2.
I'm a little concerned about

# find the active logfile (should be the last one) and delete it from the array


If the daemon didn't get around to opening a new file by the time we reach here, then we'll be out of sync.  That said, it probably doesn't matter - we'll just have one more unrotated file around until we next run, which isn't a big concern.
Take care with commands like this:

gzip &quot;${list[@]}&quot;


It's a good idea to use -- so we can be sure that filenames beginning with - aren't interpreted as options.
Also, commands such as gzip can fail - do we really want to keep going if they do?  (This question isn't so simple to answer, as one of the likely reasons is &quot;no space on device&quot;, and in that case we do want to delete some files!)