Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash Shell脚本:可编程获取POSIX系统上CPU供应商的可移植方式_Bash_Shell_Posix_Cpu Architecture - Fatal编程技术网

Bash Shell脚本:可编程获取POSIX系统上CPU供应商的可移植方式

Bash Shell脚本:可编程获取POSIX系统上CPU供应商的可移植方式,bash,shell,posix,cpu-architecture,Bash,Shell,Posix,Cpu Architecture,是否有一种可移植的方法可以通过编程在shell脚本中获取POSIX系统上的CPU供应商信息?特别是,我需要说明x86_64/AMD64 CPU是由Intel还是AMD销售的。这种方法不一定适用于所有POSIX系统,但应该适用于一系列常见的POSIX系统:GNU/Linux、MacOS和*BSD。例如,仅Linux的方法是从/proc/cpuinfo提取信息。这是您需要的基本逻辑: 检测操作系统类型:linux或BSD(如果是BSD darwin或其他BSD)。如果是其他BSD、openbsd、f

是否有一种可移植的方法可以通过编程在shell脚本中获取POSIX系统上的CPU供应商信息?特别是,我需要说明x86_64/AMD64 CPU是由Intel还是AMD销售的。这种方法不一定适用于所有POSIX系统,但应该适用于一系列常见的POSIX系统:GNU/Linux、MacOS和*BSD。例如,仅Linux的方法是从/proc/cpuinfo提取信息。

这是您需要的基本逻辑:

检测操作系统类型:linux或BSD(如果是BSD darwin或其他BSD)。如果是其他BSD、openbsd、freebsd、netbsd、蜻蜓BSD。如果是darwin,则需要特定于darwin的处理。如果不是bsd也不是linux,那么它是Unix的专有类型吗?你要试着处理它吗?如果不是,你需要一个安全的后备。这将决定您使用什么方法来执行一些(但不是全部)检测

如果是linux,如果你想要的只是intel或amd,那就很容易了,除非你需要可靠的32/64位检测,你只指定了64位,这是正在运行的内核还是cpu?因此,如果相关的话,这必须得到处理。它是什么类型的intel/amd cpu重要吗?例如,他们制造一些SOC变体

BSD的sysctl将给出每个BSD决定放入其中的任何内容。dragonfly和freebsd将是相似或相同的,openbsd您必须检查每个版本,netbsd。。。这很棘手。有些安装将需要root读取sysctl,这是您无法控制的,因此您必须逐个处理它,并进行错误处理以检测所需的root,这是不同的,通常是使其成为用户可读的数据,但并不总是如此。请注意,bsd可以而且确实会更改输出中某些字段数据的语法,因此,如果您确实需要bsd支持,则必须继续使用它。总体而言,苹果似乎一点也不关心真正的unix工具是否能够处理它们的数据,所以这是经验性的,不要假设没有几代人的输出。默认情况下,它们不包括很多标准的unix工具,因此您不能假设这些工具实际上是在一开始就安装的

/proc/cpuinfo将覆盖amd/intel的所有linux系统,可以使用多种方法确定它是运行32位还是64位,以及它是32位还是64位cpu

虚拟机可以提供帮助,但只能起到部分作用,因为cpu将是主机的,或者是主机的一部分。获取可靠、真实的当前和上一代数据是一件痛苦的事情。但是如果你有intel和amd系统可以使用,你可以安装除darwin/osx之外的大多数bsd变体,并对其进行调试,这样你就可以使用除darwin之外的大多数操作系统类型,darwin需要某种类型的mac可用

失败重要吗?如果检测失败,这真的重要吗?如果是,如何处理故障?ARM/MIPS/PPC是否重要?其他CPU呢,比如Elbrus?有许多类似英特尔的功能,但哪些不是amd或英特尔

正如评论所说,阅读inxi中的cpu块,找出您需要的,但这并不容易,而且需要大量的数据示例,您会感到悲伤,因为有一天FreeBSD或osx或openbsd将为新版本随机更改某些内容

如果您忽略OSX,并假装它不存在,好的一面是,如果您只需要通过/proc/cpuinfo进行intel/amd检测,并将其打印得尽可能整洁,那么您就可以用很少的代码获得98%的开箱即用支持。如果您必须拥有OSX,那么您必须添加完整的BSD处理程序套件,这是一个难题。就我个人而言,除非我得到报酬,否则我不会去做这样的项目。通常你可以很容易地获得FreeBSD和OpenBSD,尽管你必须检查每一个新的主要版本,看看它是否仍然有效

如果你增加了更多的需求,比如CPU而不是intel/amd,那么它就会变得更加困难,需要更多的代码

请注意,在达尔文,目前所有的osx都是我相信英特尔的,尽管有传言说苹果打算离开英特尔。以前它们是powerpc,所以这也取决于解决方案的健壮性,也就是说,如果它在mac powerpc上出现故障,你会在意吗?你在乎它在未来非英特尔驱动的mac电脑上出现故障吗


进一步注意,如果指定了BSD,则不包括各种更分散的Unix系统,如openindiana、solaris本身、ibm、hp的专有Unice等,它们都使用不同的工具。

我将继续编写精确的命令,以获得每个受支持操作系统的cpu供应商,然后为给定操作系统检测运行适当的命令集

考虑到您问题中的操作系统,我编写了一个易于改进/扩展的示例:

OS="`uname`"
case "$OS" in
  SunOS*)    /usr/platform/`uname -m`/sbin/prtdiag -v ;;
  Darwin*)   sysctl -n machdep.cpu.vendor ;;
  Linux*)    lscpu | grep Vendor | awk '{print $NF}' ;;
  FreeBSD*)  sysctl -n hw.model | awk 'NR==1{print $NF}' ;;
  *)         echo "unknown: $OS" ;;
esac

POSIX IEEE Std 1003.1-2017不强制要求持有CPU品牌。最接近的是,这是系统运行的硬件类型。不幸的是,该命令没有标准化的输出,所以 你可能会在一些较旧的机器上使用amd64,但现在大多数情况下会使用i686或x86_64

POSIX确实要求c99,一个基本的C编译器接口,在C编译器可用时出现。您可以使用它编译cpuid的原始版本:

根据cpuid说明列出了许多其他可能的供应商品牌,但对于您定义的用例来说,最有趣的可能是:

真英特尔-英特尔 AMDISBOTTER!-AMD AMD-AMD 如果路径中有这个简单的可执行文件,POSIX-y逻辑将如下所示:

if cpuid | grep -q AMD; then
    : # AMD logic here
elif cpuid | grep -q Intel; then
    : # Intel logic here
else # neither Intel nor AMD
    echo "Unsupported CPU vendor: $(cpuid)" >&2
fi
如果你有一个非常非常旧的多核主板,从AMD与Intel的引脚等效的那一天开始,那么你可能想知道CPU0和CPU1是否是同一个供应商,在这种情况下,可以在装配线上修改上面的C程序,以检查处理器1,而不是相应asm函数的第二个参数0

这说明了这种方法的一个特殊好处:如果您真正想知道的是CPU是否支持特定的功能集,并且只是使用供应商作为代理,那么您可以修改C代码来检查CPU功能是否实际可用。这是对给定给汇编代码的EAX值的快速修改,以及对E{B,C,D}X结果寄存器解释的更改

关于c99的可用性,请注意:

没有c99的POSIX兼容系统证明了该系统上没有可用的C编译器。如果您的目标系统没有c99,那么您需要选择并安装C编译器gcc、clang、msvc等,或者尝试使用eg/proc/cpuinfo进行回退检测

该标准声明,与本标准中的所有其他非OB着色实用程序不同,此名称的实用程序可能不会出现在本标准的下一版本中。本实用程序的名称与本标准批准时ISO C标准的当前版本相关联。由于ISO C标准和本标准由不同的组织按照不同的时间表维护,因此我们无法预测编译器在下一版本标准中的名称。因此,您应该考虑编译一些沿{c99:-c99 }-ocpIDID cPUID.c的行,这会让您随着二进制名随时间变化而弯曲。p>
?@jhnc是-但是如何?@jhnc:shell脚本是解释文本;对于每个不同的操作系统,运行cpuid指令都需要一个本地二进制可执行文件ELF、MachO等,除非有广泛安装的Python或其他可移植语言包装/绑定。您可以查看的源代码,看看它们是如何检索数据的。inxi是用perl编写的,perl通常是预先安装的,甚至是在OS X上。perl命令可以作为一行程序在bash内部运行。我相信posix没有指定提取cpu供应商的方法。因此,所有操作系统都是特定于操作系统的,您应该分别处理所有可能的操作系统。例如,蜻蜓属于freebsd系列,pcbsd和其他变体也是如此,因此一般来说,您需要确定它的数据将位于哪个bsd组,每个bsd都坚持它是自己的操作系统,即使它们通常只是一个主要的变体。基本上,你只需几行代码就可以覆盖88%使用linux的nix系统,然后你在处理bsd时会遇到一大堆麻烦,这是一个收益递减的问题,如果你在这一点上做这项工作是否会得到报酬。我将bsd支持视为操作系统的编程工时/用户基数。这就产生了Linux,然后是Freebsd/dragonfly/pcbsd和相关的,然后是openbsd,然后是远远落后于这些的netbsd。然后是opensolaris和相关的。。。除了OSX,它不是免费软件,所以不算。然后,如果检测突然受到特性爬行的影响,那么再次,忘记它,然后停止,除非你得到了工作的报酬,或者暂时被问题困扰。对于posix类型的跨平台/操作系统支持,键入一个问题很容易,但实际实现它是完全不同的。@Pitto我想这将涉及在每台服务器上部署软件-但这怎么不可行?echo$code>/tmp/cpuid.c&&c99-o/tmp/cpuid-cpuid.c&/tmp/cpuid|grep-q AMD非常简单,并且可以通过POSIX方式可靠地完成任务,而无需了解、跟踪和维护操作系统和操作系统版本特定的命令。不允许在服务器上安装软件安全/风险。使用标准操作系统工具将是更简单的方法-我们可能不得不同意这里的不同意见。在/tmp或$HOME/tmp中编译程序在我30年来管理的任何服务器上都从未被阻止过。虽然我通常倾向于使用标准工具,但事实是,没有任何一种标准工具可以获取这些信息。是的,除了两件事:1.你的达尔文分支在Hackintosh补丁上不工作,尽管可以说这是他们实现中的一个bug n和2您需要规范化输出,这样消费者就不必知道所有这些变化的所有可能输出。可能需要担心的是,sysctl中的值可能会被欺骗,因此不可靠,并且b您没有说明OSTYPE应该如何填充-这是bash ism,而不是POSIX。如果c99不可用,可能会返回cc。当然,这不是保证,但它也很可能存在。ifdef\u WIN32也许您想要ifdef\u MSC\u VER。除非MinGW或Cygwin GCC不定义WIN32或定义cpuidex?还值得指出的是,GCC/clang附带了一个cpuid.h包装器。不过,不确定便携式CPU检测的状态是否为C。还有CPUID表。
$ c99 -o cpuid cpuid.c && ./cpuid # MacOS X
GenuineIntel
$ c99 -o cpuid cpuid.c && ./cpuid # Intel-based AWS EC2 (M5)
GenuineIntel
$ c99 -o cpuid cpuid.c && ./cpuid # AMD-based AWS EC2 (T3a)
AuthenticAMD
if cpuid | grep -q AMD; then
    : # AMD logic here
elif cpuid | grep -q Intel; then
    : # Intel logic here
else # neither Intel nor AMD
    echo "Unsupported CPU vendor: $(cpuid)" >&2
fi