Sto*_*row 6 linux filesystems mount rename
一个cpp
我正在使用的文件创建一个目录,即mkdir( path, ... )
,在路径来自一个环境变量(例如getenv( "FOO" );
)。
例如,上面创建的$FOO
is/foo
和path
是 `/foo/newPath/'。
对于我的问题的情况下,有可能/foo/oldPath/
存在,并且有内容(假设没有进一步的子目录),在这种情况下,我想从移动文件/foo/oldPath/
到/foo/newPath
。
我的问题是:因为/foo/newPath/
是作为$FOO
, 即的子目录创建的/foo/newPath/
并且/foo/oldPath/
具有相同的父目录,所以是否保证两个目录都在同一个“挂载的文件系统”上?我对 Linux 上的挂载点和文件系统的了解充其量是微不足道的。
这个问题背后的背景是:如果/foo/newPath/
和/foo/oldPath/
保证在同一个挂载的文件系统上,我可以使用rename()
比其他替代方法更容易地执行文件移动。该函数的手册页说,如果oldPath
和newPath
不在同一个“挂载的文件系统”上,它将失败。
cun*_*mp3 14
他们不能保证。这可能/foo/oldPath
是一个挂载点。
但是,这可以通过运行mount | grep 'on /foo/oldPath'
No output should表明该oldPath
目录不是挂载点来轻松检查。
如果您使用嵌套目录,则需要更加小心,因为您可以在任何地方拥有安装点。
我不确定这是否是自动化的,但值得注意的是,mount 的第三个字段(空格分隔)是每行的安装点,因此可以使用 an cut -d ' ' -f 3
来提取路径(您是否需要验证它是不仅仅是另一个挂载点的子字符串,例如/foo/oldPath/nested/mountPoint
)
如果您想将其转换为 C/C++ 代码,您可以使用system("mount | grep 'on /foo/oldPath'")
,但我不会发誓。如果需要,您可能会在 StackOverflow 上获得更多的实现细节。
由于各种原因(在其他答案中详细说明),您不应该尝试此操作:/foo/oldPath
本身可能是挂载点,或者可能存在覆盖文件系统并阻止移动文件。您甚至可能会在单个文件上遇到绑定挂载,这也会在重命名文件时导致问题。
与其提前确定文件是否可以重命名,不如尝试重命名它们并处理错误。rename
如果发生错误,将返回 -1,如果由于交叉安装问题而无法重命名,errno
则将设置为EXDEV
。然后您可以以另一种方式继续(复制和删除)。
通常,要确定两个文件系统对象是否在同一个文件系统上,您应该stat
对它们运行并查看设备标识符(中的st_dev
字段struct stat
)。同一文件系统上的两个文件系统对象将具有相同的设备标识符。