To rotate logs, you should really use logrotate.
If you can't rely on logrotate being available, here's a way do it inside the shell. To keep things simple, I'll assume that nothing else (including another instance of your script) will try to rename the log files while your script is running.
The easiest approach is to recursively rename log N+1 before actually renaming log N to N+1. The shell can perform all the necessary arithmetic, you don't need sed
here. Note that while recursive functions are possible in a POSIX shell, there are no local variables other than the positional parameters (many shells offer local variables as an extension).
#!/bin/sh
## Move "$1.$2" to "$1.$(($2+1))", first rotating the target as well.
rotate () {
if [ -e "$1.$(($2+1))" ]; then rotate "$1" $(($2+1)); fi
mv -- "$1.$2" "$1.$(($2+1))"
}
for x; do
## Break each argument into FILE.NUMBER or just FILE.
suffix=${x##*.}
case $suffix in
*[!0-9]*)
if [ -e "$x.0" ]; then rotate "$x" 0; fi
mv -- "$x" "$x.0";;
*) rotate "${x%.*}" "$suffix";;
esac
done
Regarding what you've written, note that echo ${file}
is bad for two reasons: most importantly, if ${file}
contains any special characters such as white space, the shell will interpret them; also, with some shells, echo
itself will interpret backslashes and possibly a leading -
. So you should always write printf %s "$file"
instead.