我正在尝试编写一个跨平台命令行来查找文件系统上的所有本地文件。
我的目的是使用该find
命令,仅使用 POSIX 参数。有没有办法跳过远程文件系统上的文件,同时仅限于 POSIX 命令,并且无需编程?
我当前的命令行是
find -type f -print
但这显然列出了每个常规文件,而不仅仅是本地文件。
我知道这个-local
标志,但据我所知,它不是 POSIX 或跨平台标准的其他部分。 locate
似乎也不跨平台。我也不认为该-xdev
标志是我正在寻找的,因为我想搜索所有本地安装的文件系统 - 如果/
和/home
都是本地的,并且我运行find / -xdev -print
,find
应该跳过/home
(除非我误解了东西)。
就其价值而言,以下 URL 是有用的资源......
答案1
我不认为有任何方法可以仅使用 POSIX 接口来确定文件系统是远程的还是本地的。 POSIX 甚至不强制执行mount
命令,据我所知,所有对文件系统的引用都充满了“实现定义”一词。
-local
该命令的主要内容没有find
太大帮助,因为它仅在 Solaris 上可用,并且它取决于列出远程文件系统类型的配置文件是否存在。
POSIX 确实强制执行df
命令,并且如果该命令与标志一起使用,则需要特定的输出格式-P
;在该格式中,有六个空格分隔的字段,其中第一个是“文件系统的名称,采用实现定义的格式”,最后一个是挂载点。
您需要的是与本地文件系统对应的所有安装点的列表。在这里,我认为你将不得不退回到启发式;这是排除“看起来像”远程文件系统的文件系统名称。一些例子:
//... CIFS (Samba)
host:... NFS
/afs AFS
这并不是一份详尽的清单,而且完全没有任何保证。
如果您随后从输出中过滤掉这些行df
,然后删除前五列,则可以将列表提供给find
具有主列表的命令-xdev
。
即使这听起来似乎有道理,但实际上并不能保证文件系统实际上已“挂载”(请参阅 AFS)或文件系统完全是本地的或完全远程的(基于熔断器的文件系统可以任意重定向单个文件)。因此,我的建议是谨慎行事。
答案2
这-xdev
可行,但可能不是你想要的方式,即如中所述POSIX
find
男人:find -xdev
运行直到遇到不同的 FS Device ID
(可以使用stat
实用程序或stat()
系统调用进行检查):
例如linux
:
# stat /home/foo
File: `/home/foo'
. . .
Device: fd02h/64770d
. . .
# stat /boot/foo
File: `/boot/foo'
. . .
Device: 801h/2049d
. . .
让我们通过以下方式找到它-xdev
:
# find / -xdev -name foo -print
#
没有:
# find / -name foo -print
/home/foo
/boot/foo
检查:Device ID
Solaris
# truss -t lstat64 -v lstat64 ls /foo
lstat64("/foo", 0xFFBFFC48)
d=0x02580000 . . .
# truss -t lstat64 -v lstat64 ls /etc/foo
lstat64("/etc/foo", 0xFFBFFB88)
d=0x02580000 . . .
# truss -t lstat64 -v lstat64 ls /opt/foo
lstat64("/opt/foo", 0xFFBFFC48)
d=0x02580004 . . .