从类Unix系统获取唯一的ID

我想从任何类Unix系统(如果可能的话)获得一个唯一的ID,每当我的应用程序运行在同一台机器上时,这个ID将是持久的。 如果可能的话,我想从Linux或FreeBSD或Solaris等得到相同的ID …我不想为每台机器生成一个新的ID,但得到一个已经存在的ID,我更喜欢这个ID来自操作系统,我不喜欢使用像MAC地址的东西。

如果没有其他选项可用,我可以将MAC与其他选项结合使用,例如,id可以是MAC地址和其他内容的组合的md5散列。

我想听听你的build议。

如果它是有用的,我的应用程序是用C / C ++编写的。

所有这些的目的是防止用户运行我的应用程序两次或更多次。 我只想跑一次。

Solutions Collecting From Web of "从类Unix系统获取唯一的ID"

如何根文件系统的UUID? 您可以通过手动解析文件或使用getfsent (3)getfsfile (3)/etc/fstab获取根文件系统设备。 获得设备后,可以通过检查/dev/disk/by-uuid的链接或blkid命令来获取UUID。

Solaris和Linux都提供了hostid (1)实用程序

像往常一样,最好的办法就是看看其他人已经解决了同样的问题。

FLEXlm还为其节点锁定许可证使用主机标识符。 它使用的最常见的主机标识符是一个网络接口的以太网MAC地址,无需任何分隔符即可粉碎。

它还可以使用(在Windows上)C:驱动器的卷序列号(再次捣毁而没有任何分隔符),在Solaris上输出hostid命令(IIRC,在Sun计算机上,这个号码实际上是唯一的,并且位于在系统板上的小型可移动EEPROM上)。

虽然MAC地址非常容易伪造,但它现在几乎是一个普遍的标识符(几乎所有的新计算机都至少有一个以太网端口,而且这些端口很常见),而且实际上是打算全球唯一的事实上,以太网协议取决于这个独特性)。 这种方法会遇到的主要问题是:

  • 有些电脑有几个以太网地址; 其中一些在主板上,一些在单独的可移动卡上。
  • 它们极易伪造(有些协议依赖于能够改变它们)。
  • 一些虚拟化环境在每次启动时都会产生随机的以太网地址(但是它们通常会强制固定值)。

另一个选择是使用来自dmidecode的信息,这是一个在linux上的命令。 该信息从/ dev / mem解码,因此需要root访问权限。

dmidecode读取的信息已知是有缺陷的,因为一些主板制造商谎言或假冒某些领域。

没有一个通用而可靠的方法来获得你想要的东西。

我不认为这是可能的。 你可以得到最接近的是创建一个非常长的随机字符串(如MS与GUID做),并将其存储在您的系统的某个地方。

你必须考虑很多设置可能已经创建了一个文件系统镜像,并克隆到许多机器,而不是单独设置它们。 在其他情况下,机器可以重新设置多次。 换句话说,操作系统提供的任何东西都是不可信的。

但是,CPU确实保持唯一的序列号,但在不同的系统上访问它应该是不同的。

您没有提到唯一标识符需要多么稳定 – 您是否总是希望每次运行代码时,同一个主机都能生成相同的ID?

如果没有,那么fuzzymonk的uuidgen的建议是你想要的。

如果是,那么你需要决定什么构成“相同”就主人而言。 其中一种方法就是像你所建议的那样,第一个以太网接口的MAC和“某物”的MD5总和。 对于这种情况下的“东西”,我会考虑FQDN,除非你的“相同主机”的概念包括FQDN更改…

你可以得到根文件系统的UUID,这是相当可靠的,但它不会区分运行在同一个磁盘上的chroot和vms。

如果您主要处理专用于运行特定操作系统的内置或静态HDD,则应该能够使用根文件系统的UUID来检测系统。

你可以用这样的东西得到root fs的UUID: alias sys_guid='sudo /sbin/blkid | grep "$(df -h / | sed -n 2p | cut -d" " -f1):" | grep -o "UUID=\"[^\"]*\" " | sed "s/UUID=\"//;s/\"//"' alias sys_guid='sudo /sbin/blkid | grep "$(df -h / | sed -n 2p | cut -d" " -f1):" | grep -o "UUID=\"[^\"]*\" " | sed "s/UUID=\"//;s/\"//"'

如果您需要进一步区分同一操作系统的内核版本,或者在同一磁盘上运行不同的操作系统,则可以使用uname数据和/或将它们与root用户UUID结合使用。

听起来你正在寻找UUID。 这是一个普遍唯一的id(与GUID实际上是一样的)

在不同的库中有很多C ++实现,或者你可以使用uuidgen命令并捕获输出。

大多数类似unix的机器都有一个可以通过/ dev / random访问的随机数生成器。 你将需要像MAC地址和时间给GUID发生器一个真正的唯一性(这是Windows上的GUID生成器)。 最重要的是,从/ dev / random中得到一些东西会给你一个合理的GUID类型构造。 在实践中,UUID库在幕后做这种事情。

如果每台机器只需要一个号码,那么MAC地址可能就足够了。 这些由中央机构管理,可以合理地假设没有两个MAC地址是相同的。 但是,如果您试图使用此功能将软件安装绑定到MAC地址,请注意某些组件具有可编程的MAC地址或MAC地址的可编程组件。 类Unix的操作系统,尤其是开源的操作系统往往没有硬连线的序列号。 这种方法也可能导致在VM中运行软件的多个实例的问题。

一个选项可能是一个USB 加密狗,它可以从几个制造商处获得。 另一种选择可能是许可证服务器,其中唯一的代码被提供给服务器。 再次,几种罐装解决方案可以从不同的渠道获得。

你提到在Windows上你使用了一些GUID …你有关于它是如何创建的一些细节?

除此之外,你可以尝试像CPU ID或硬盘ID …我想这些不能改变(但如果更换有问题的硬盘,你会遇到麻烦)。

Jason Day和A.Danischewski的回答似乎是正确的,但是由于/sbin/blkid/etc/fstab在OSX上不存在,所以不符合任何“类Unix系统”的标准。

唯一的100%可移植的方法是为自己的应用程序将创建的文件选择一个标准位置,例如/etc/YOURAPP.cfg ,如果不存在,则将UUID存储在那里。

很不理想,因为其他人或应用程序可能会删除文件或更改文件,或者如果用户更改了根文件系统,则可能会丢失当前机器的ID,或者可能会在另一台机器上生成该ID。 更不用说读写权限等问题了。

但最终没有“同一台机器”这样的东西。 任何一台电脑都不会少于它的组件+当前配置。 我觉得你可以做得比这更好。

你可以在如下地方使用lockfile:

  • /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()); 

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