从类 Unix 系统获取唯一 ID

2024-10-24 08:50:00
admin
原创
110
摘要:问题描述:我想从任何类 Unix 系统(如果可能的话)获取一个唯一的 ID,每次我的应用程序在同一台机器上运行时,该 ID 都会保持不变。如果可能的话,我想从 Linux、FreeBSD 或 Solaris 等获取相同的 ID... 我不想为每台机器生成一个新的 ID,而是获取一个已经存在的 ID,我希望这个...

问题描述:

我想从任何类 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());

如果打开失败,请检查该进程是否仍在运行,如果没有,请删除该文件并重试。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   681  
  在项目管理领域,集成产品开发(IPD)流程以其高效、协同的特点,被众多企业视为提升产品竞争力的关键。IPD流程强调跨部门、跨职能的紧密合作,以确保产品从概念到市场各个环节的无缝衔接。然而,实现这一目标并非易事,它需要企业深刻理解并掌握IPD流程中的跨部门协作艺术。本文将深入探讨IPD流程中跨部门协作的三个关键点,旨在为...
IPD项目管理咨询   9  
  掌握IPD流程图:提升团队协作的关键路径在当今快速变化的商业环境中,团队协作的效率与效果直接关系到项目的成功与否。集成产品开发(Integrated Product Development,简称IPD)作为一种先进的研发管理理念,通过跨部门、跨领域的协同工作,能够显著提升产品开发的速度与质量。而IPD流程图,则是这一理...
IPD流程阶段   9  
  IPD流程概述:理解其核心价值与实施背景集成产品开发(Integrated Product Development,简称IPD)是一种先进的产品开发管理理念,它强调跨部门协作、市场导向和快速响应变化的能力。IPD流程不仅关注产品本身的技术创新,更注重将市场、研发、生产、销售等各个环节紧密集成,以实现产品从概念到市场的高...
华为IPD是什么   7  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程以其跨部门协作、高效决策和快速响应市场变化的特点,被众多企业视为提升竞争力的关键。然而,实践IPD流程并非易事,项目管理中的种种错误往往阻碍了其效果的充分发挥。本文旨在深入探讨如何在实施IPD流程时避免这些常见错误,...
IPD框架   7  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用