![创建符号链接会导致无法覆盖目录错误](https://linux22.com/image/1525277/%E5%88%9B%E5%BB%BA%E7%AC%A6%E5%8F%B7%E9%93%BE%E6%8E%A5%E4%BC%9A%E5%AF%BC%E8%87%B4%E6%97%A0%E6%B3%95%E8%A6%86%E7%9B%96%E7%9B%AE%E5%BD%95%E9%94%99%E8%AF%AF.png)
我有一个带有 postgresql 后端的 Django 应用程序。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”和目标上的“pgsql_tmp”也相同。如果目标目录名称不同,则使用如下所示的开关 T。
ln -sfT /$PGDATA/base/pgsql_tmp /mnt/new_dir