从类 Unix 系统获取唯一 ID
- 2024-10-24 08:50:00
- admin 原创
- 110
问题描述:
我想从任何类 Unix 系统(如果可能的话)获取一个唯一的 ID,每次我的应用程序在同一台机器上运行时,该 ID 都会保持不变。如果可能的话,我想从 Linux、FreeBSD 或 Solaris 等获取相同的 ID... 我不想为每台机器生成一个新的 ID,而是获取一个已经存在的 ID,我希望这个 ID 来自操作系统,我不喜欢使用 MAC 地址之类的东西。
如果没有其他可用选项,我可以将 MAC 与其他内容组合使用,例如 id 可以是 MAC 地址与其他内容组合的 md5 哈希值。
我愿意听取你的建议。
如果有用的话,我的应用程序是用 C/C++ 编写的。
所有这些的目的是为了防止用户运行我的应用程序两次或多次。我只想运行一次。
解决方案 1:
那么根文件系统的 UUID 又如何呢?您可以通过 来获取根文件系统设备/etc/fstab
,方法是手动解析文件,也可以使用getfsent (3)
或。一旦您获得了设备,您可以通过检查或命令getfsfile (3)
中的链接来获取 UUID 。/dev/disk/by-uuid
`blkid`
解决方案 2:
通常,最好的方法是看看其他人是如何解决同一问题的。
FLEXlm还为其节点锁定许可证使用主机标识符。它使用的最常见主机标识符是您的某个网络接口的以太网 MAC 地址,该地址拼凑在一起,没有任何分隔符。
它还可以使用(在 Windows 上)C:驱动器的卷序列号(再次混合在一起而没有任何分隔符),在 Solaris 上,可以使用hostid
命令的输出(IIRC,在 Sun 计算机上,这个号码实际上是唯一的,并且位于系统板上的一个小型可移动 EEPROM 上)。
虽然 MAC 地址极易伪造,但如今它几乎是一个通用标识符(几乎所有新计算机都至少有一个以太网端口,并且它们通常安装在机上),并且实际上旨在具有全球唯一性(事实上,以太网协议依赖于这种唯一性)。使用这种方法的主要问题如下:
有些计算机有多个以太网地址;有些位于主板上,有些位于单独的可移动卡上。
它们极易被伪造(并且某些协议依赖于能够改变它们)。
一些虚拟化环境在每次启动时都会生成随机以太网地址(但它们通常有办法强制使用固定值)。
解决方案 3:
Solaris 和 Linux 都提供了hostid
(1) 实用程序
解决方案 4:
另一个选择是使用来自dmidecode ( Linux 上的一个命令)的信息。此信息是从 /dev/mem 解码的,因此需要 root 访问权限。
dmidecode 读取的信息已知存在缺陷,因为一些主板制造商会在某些字段上撒谎或伪造。
解决方案 5:
没有通用且可靠的方法来获得你想要的东西。
解决方案 6:
我认为这是不可能的。最接近的方法是创建一个非常长的随机字符串(就像 MS 对 GUID 所做的那样)并将其存储在系统的某个位置。
解决方案 7:
您必须考虑到,许多设置可能已创建文件系统映像并克隆到多台机器,而不是单独设置它们。在其他情况下,一台机器可能会重新设置多次。换句话说,操作系统提供的任何东西都不可信任。
但是,CPU 确实保留了唯一的序列号,但是在不同的系统上对它的访问应该是不同的。
解决方案 8:
您可以获取根文件系统的 UUID /
,它相当可靠,但它不会区分在同一磁盘上运行的 chroot 和可能的 vms。
如果您主要处理专用于运行特定操作系统的内部或静态 HDD,那么您应该能够使用根文件系统的 UUID 来检测系统。
您可以使用以下命令获取根文件系统的 UUID: alias sys_guid='sudo /sbin/blkid | grep "$(df -h / | sed -n 2p | cut -d" " -f1):" | grep -o "UUID="[^"]*" " | sed "s/UUID="//;s/"//"'
如果您需要进一步区分同一操作系统的内核版本,或在同一磁盘上运行的不同操作系统,您可以使用来自根文件系统 UUID 的数据uname
和/或将它们与根文件系统 UUID 相结合。
解决方案 9:
正如其他人所说,该dmidecode
命令是一个选项。
[root@sri-0000-0003 WebGui]# dmidecode -s system-uuid
03001234-1234-1234-1234-000700012345
我编辑了输出以隐藏我测试的系统的 UUID。
您还可以从 dmidecode 获得其他内容。 dmidecode -t
它会告诉您类别。
[root@sri-0000-0003 WebGui]# dmidecode -t
dmidecode: option requires an argument -- 't'
Type number or keyword expected
Valid type keywords are:
bios
system
baseboard
chassis
processor
memory
cache
connect
如果您使用实际硬件而不是虚拟机,那么这dmidecode -t processor
将是一个不错的选择。
[root@sri-0000-0003 WebGui]# dmidecode -t processor
# dmidecode 3.1
Getting SMBIOS data from sysfs.
SMBIOS 3.0.0 present.
Handle 0x0041, DMI type 4, 48 bytes
Processor Information
Socket Designation: U3E1
Type: Central Processor
Family: Core i3
Manufacturer: Intel(R) Corporation
ID: E3 00 00 00 11 22 33 44
鉴于处理器制造商的数量很少,这似乎是 的一个很好的替代品dmidecode -s system-uuid
。然而,在 virtualbox 下,dmidecode -t processor
不会给你任何有用的东西。我不知道其他虚拟平台。
我敢打赌它dmidecode -s system-uuid
也可以在 Docker 容器中工作,但我无法验证这一点。
解决方案 10:
您没有提到唯一标识符需要多么稳定——您是否总是希望每次运行代码时同一个主机都生成相同的 ID?
如果没有,那么 fuzzymonk 建议的 uuidgen 就是您想要的。
如果是,那么您需要确定就主机而言什么构成“相同”。一种方法是,如您所建议的,第一个以太网接口的 MAC 和“某物”的 MD5 总和。对于那种情况下的“某物”,我会考虑 FQDN,除非您的“同一主机”概念包括 FQDN 更改...
解决方案 11:
您提到在 Windows 上您使用了一些 GUID...您是否知道它是如何创建的?
除此之外,您可以尝试 CPU ID 或硬盘 ID 之类的东西......我想这些是无法改变的(但如果更换有故障的硬盘,您就会遇到麻烦)。
解决方案 12:
Jason Day 和 A.Danischewski 的回答似乎是正确的,但不符合您对任何“类 Unix 系统”的标准,因为/sbin/blkid
它/etc/fstab
在 OSX 上并不存在。
唯一 100% 可移植的方法是选择一个由您自己的应用程序创建的文件的标准位置,例如,/etc/YOURAPP.cfg
如果尚不存在 UUID,则将其存储在那里。
这远非理想,因为其他人或应用程序可能会删除或更改该文件,或者如果用户更改了根文件系统,您可能会丢失当前计算机的 ID,或者它可能出现在另一台计算机上。更不用说读写权限等问题了。
但归根结底,没有“同一台机器”这种说法。任何计算机都只不过是其组件 + 当前配置。我认为在便携性方面,你不可能做得比这更好。
解决方案 13:
听起来您正在寻找 UUID。这是一个通用的通用唯一 ID(实际上,与 GUID 相同)
不同的库中有许多 C++ 实现,或者您可以使用 uuidgen 命令并捕获输出。
解决方案 14:
大多数类 Unix 机器都有一个可通过/dev/random访问的随机数生成器。您需要 MAC 地址和时间之类的东西来为 GUID 生成器提供真正的唯一性(这是 Windows 上的 GUID 生成器所做的)。除此之外,从 /dev/random 获取某些东西将为您提供一个相当不错的 GUID 类型构造。实际上,UUID 库在后台执行此类操作。
如果您只需要每台机器一个号码,那么 MAC 地址可能就足够了。这些由中央机构管理,可以合理地假设没有两个 MAC 地址是相同的。但是,如果您尝试使用它将软件安装与 MAC 地址绑定在一起,请注意某些组件具有可编程 MAC 地址或 MAC 地址的可编程组件。类 Unix 操作系统,特别是开源操作系统往往没有硬连线序列号。这种方法还可能导致在 VM 中运行软件的多个实例时出现问题。
一种选择可能是 USB加密狗,可以从多个制造商处获得。另一种选择可能是许可证服务器,其中唯一代码提供给服务器。同样,可以从不同来源获得几种现成的解决方案。
解决方案 15:
您可以在以下地方使用锁文件:
/var/run/yourapp.pid (如果程序由 root 运行)
$HOME/.yourapp.pid(如果由用户和本地文件系统运行)
$HOME/.yourapp.$(hostname -f).pid (nfs 上的主目录)
当你的程序运行时,它会执行类似以下的操作:
lock = open(filename, O_CREAT | O_EXCL);
dprintf(lock, "%u", getpid());
如果打开失败,请检查该进程是否仍在运行,如果没有,请删除该文件并重试。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件