Это не ваша очевидная непосредственная проблема, но конструкция if
неверна: она вводит время проверки для состояния гонки по времени использования . В промежутке между проверкой if [ -f
и mv
может возникнуть какой-то другой процесс и что-то изменить, чтобы вы больше не могли перемещать файл, даже если проверка прошла успешно.
Чтобы избежать этого класса ошибок, всегда пишите код, который запускает , пытаясь выполнить операцию, которую вы хотите выполнить, а затем, если она не удалась, выясните, почему. В этом случае вам ничего не нужно делать, если исходный файл не существует, но сообщать об ошибке, если операция не удалась по какой-либо другой причине. Нет хорошего способа сделать это в портативной оболочке, вам нужно что-то, что позволит вам проверить errno
. Я, вероятно, написал бы этот помощник C:
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "usage: %s source destination\n", argv[0]);
return 2;
}
if (rename(argv[1], argv[2]) && errno != ENOENT) {
fprintf(stderr, "rename '%s' to '%s': %s\n",
argv[1], argv[2], strerror(errno));
return 1;
}
return 0;
}
, а затем используйте его так:
renameLogs()
{
( cd "$MY_DIR/logs"
rename_if_exists ServiceFileName_0.log ServiceFileName_0.log.$(date +%M%H%S)
)
}
Конструкция ( cd
решает вашу непосредственную проблему и, в отличие от других предложений, избегает другой гонки , в которой возникает какой-то другой процесс, и портится в каталоге logs
или его родительских каталогах.
Дополнение к обязательному написанию сценариев оболочки: всегда заключайте расширения переменных в двойные кавычки, кроме тех редких случаев, когда вы хотите расширение, которое может быть разделено на слова.