File exists при создании файла или сокета
Сообщение File exists (номер 17, EEXIST) означает, что объект уже есть. У служб это обычно остатки прежнего запуска: unix-сокет, файл блокировки, временный каталог.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Остался unix-сокет от прежнего запуска
Файл сокета не удаляется при аварийном завершении. Новый запуск не может создать его заново.
-
Файл блокировки не убран
Программы с защитой от повторного запуска оставляют файл. Он же мешает следующему старту.
-
Каталог уже существует с другим владельцем
Попытка создать каталог службы поверх существующего с другими правами тоже даёт эту ошибку.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Остатки прежнего запуска в каталоге времени работы.
sudo ls -l /run/myapp/ 2>/dev/nullУправляет ли systemd этим каталогом.
systemctl show myapp.service -p RuntimeDirectory -p RuntimeDirectoryPreserveРешение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Файл сокета не удаляется при аварийном завершении. Новый запуск не может создать его заново.
- Как проверить
-
Посмотрите файл сокета и процессы.
sudo ls -l /run/myapp/app.sock 2>/dev/null pgrep -a myapp
- Как исправить
-
Удалите файл при отсутствии процессов или объявите каталог через
RuntimeDirectory=: systemd очистит его сам при остановке.
- Почему происходит
- Программы с защитой от повторного запуска оставляют файл. Он же мешает следующему старту.
- Как проверить
-
Посмотрите файл и его дату.
sudo ls -l --time-style=full-iso /run/myapp.lock 2>/dev/null
- Как исправить
- Удалите файл после проверки, что процессов нет, и перенесите его в каталог времени работы службы.
- Почему происходит
- Попытка создать каталог службы поверх существующего с другими правами тоже даёт эту ошибку.
- Как проверить
-
Посмотрите права каталога.
sudo ls -ld /run/myapp /var/lib/myapp 2>/dev/null
- Как исправить
- Приведите владельца в порядок или используйте параметры каталогов systemd: они сами следят за правами.
Пример вывода
Остался сокет от прежнего запуска. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
myapp[4300]: fatal: listen unix /run/myapp/app.sock: bind: address already in use (file exists)
$ sudo ls -l /run/myapp/app.sock
srwxr-xr-x 1 app app 0 Sep 15 15:40 /run/myapp/app.sock
$ pgrep -c myapp
0
Связанные ошибки
- status=233/RUNTIME_DIRECTORY в systemd Код 233/RUNTIME_DIRECTORY: не удалось подготовить каталог службы в /run из RuntimeDirectory=. Права, режим, удаление при остановке.
- Address already in use при запуске службы Порт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Устаревший pid-файл мешает запуску Служба считает, что уже работает: остался pid-файл после аварийного завершения.
- Bad file descriptor в журнале службы Ошибка 9 при операции с файлом: дескриптор закрыт или не тот. Разбор для служб и сокет-активации.
- Argument list too long в службе или скрипте Список аргументов слишком длинный: подстановка имён файлов дала тысячи аргументов. Как переписать вызов.
- Could not open file и cannot open shared object file Программа не может открыть файл или библиотеку: путь, права, отсутствующая зависимость сборки, изоляция.
- Device or resource busy при операции с файлом Ошибка 16: файл или устройство заняты. Разбор для точек монтирования, устройств и файлов конфигурации.
- MySQL: Can't connect to local server through socket Клиент не находит unix-сокет MySQL: сервер не запущен, путь к сокету другой, каталог в /run не создан.
Источники
- bind(2): ошибка EADDRINUSE для unix-сокетов
-
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено убийством процесса с оставшимся файлом сокета.