Создание символической ссылки приводит к ошибке «Невозможно перезаписать каталог»

Создание символической ссылки приводит к ошибке «Невозможно перезаписать каталог»

У меня есть приложение Django с бэкендом postgresql. Postgresql время от времени создает временные файлы — это может быть убийственно, если дисковое пространство критично (как в моем случае).

Один из способов решения проблемы — создать символическую ссылку на другое место хранения, где дисковое пространство не является узким местом. В моем случае postgresql хранит временные файлы в /$PGDATA/base/pgsql_tmp. У меня большой SSD-диск смонтирован в /mnt, поэтому я хочу, чтобы временные файлы находились там. Следующее должно это исправить:

ln -sTf /mnt/pgsql_tmp $PGDATA/base/pgsql_tmp
chown -R postgres /mnt/pgsql_tmp #ensuring user 'postgres' has the right perms
chmod o+x /mnt

Прежде чем сделать это в продакшене, я решил протестировать это локально. Я создал /mntи /pgsql_tmpна своем десктопе, а затем попробовал ln -sTf /home/hassan/Desktop/mnt/pgsql_tmp /home/hassan/Desktop/pgsql_tmp.

Но это в итоге дает мне ln: ‘/home/hassan/Desktop/pgsql_tmp’: cannot overwrite directory. Может кто-нибудь указать, что я делаю не так? Будучи новичком, я действительно пытаюсь понять, как это работает.

решение1

Лучшим вариантом будет удалить его ~/pgsql_tmpи позволить команде ln создать его.

Во-первых, обратите внимание, чтоЛНне связывает два объекта; он создает ссылку на цель с определенным именем из определенного места.

ln [OPTION]... [-T] TARGET LINK_NAME

Когда вы создаете ссылку с помощью ln, аргумент NAME должен указывать на объект, который еще не существует, и он будет создан в результате команды. В вашем случае вы уже создали его ( ~/pgsql_tmp) как каталог.

Обычно, Вы можете использовать переключатель -f, чтобы принудительно удалить все, что уже перекрывает путь NAME, но в вашем случае вы указали, -Tчто означает, что вы хотите создать ссылку как Файл, а не как Каталог. Поэтому, когда -fидет перезапись объекта в NAME, он пытается перезаписать каталог файлом.

Итак, вы можете либо создать ссылку как каталог и использовать -f, либо удалить объект, который перекрывает NAME, а затем создать свою ссылку. Последний вариант является лучшим.

#create a test target with a file, but without an object at lnname
~/tmp$ mkdir lntarget
~/tmp$ touch lntarget/contentfile1
~/tmp$ ln -sTf lntarget lnname
~/tmp$ ls ./lnname
contentfile1

решение2

Я знаю, что это старый вопрос, но хочу добавить больше подробностей.

Согласно вашему вопросу ваш Источник = "/$PGDATA/base/pgsql_tmp" Назначение = "/mnt/pgsql_tmp"

Так что в месте назначения вам не нужно упоминать "pgsql_tmp", когда вы запускаете "ln -sf", он создаст новый "pgsql_tmp" или, если он уже существует, то он просто свяжет его с источником. Так что ваша команда должна быть следующей.

ln -sf /$PGDATA/base/pgsql_tmp /mnt/

Вышеупомянутый случай - это когда вы хотите иметь ссылку назначения с тем же именем, что и источник, например, "pgsql_tmp" находится на источнике, и она будет такой же на месте назначения. Если имя каталога назначения отличается, то используйте переключатель T, как показано ниже.

ln -sfT /$PGDATA/base/pgsql_tmp /mnt/new_dir

Связанный контент