我想将我的 .bashrc
和 .bash_login
文件保留在版本控制中,以便我可以在我使用的所有计算机之间使用它们。 问题是我有一些特定于操作系统的别名,因此我正在寻找一种方法来确定脚本是否在 Mac OS X、Linux 或 Cygwin。
在 Bash 脚本中检测操作系统的正确方法是什么?
I would like to keep my .bashrc
and .bash_login
files in version control so that I can use them between all the computers I use. The problem is I have some OS specific aliases so I was looking for a way to determine if the script is running on Mac OS X, Linux or Cygwin.
What is the proper way to detect the operating system in a Bash script?
发布评论
评论(23)
我认为以下应该有效。 不过我不确定
win32
。I think the following should work. I'm not sure about
win32
though.对于我的 .bashrc,我使用以下代码:
然后我做类似的事情:
它很丑陋,但它有效。 如果您愿意,可以使用
case
代替if
。For my .bashrc, I use the following code:
Then I do somethings like:
It's ugly, but it works. You may use
case
instead ofif
if you prefer.bash 手册页 表示变量
OSTYPE
存储操作系统的名称:这里设置为
linux-gnu
。The bash manpage says that the variable
OSTYPE
stores the name of the operating system:It is set to
linux-gnu
here.$OSTYPE
您可以简单地使用预定义的
$OSTYPE
变量,例如:但是它是 旧版 shell 无法识别(例如 Bourne shell)。
uname
另一种方法是根据
检测平台uname命令。
请参阅以下脚本(准备包含在 .bashrc 中):
您可以在我的
.bashrc< 中找到一些实际示例/代码>
。
这是 Travis 上使用的类似版本CI:
$OSTYPE
You can simply use pre-defined
$OSTYPE
variable e.g.:However it's not recognized by the older shells (such as Bourne shell).
uname
Another method is to detect platform based on
uname
command.See the following script (ready to include in .bashrc):
You can find some practical example in my
.bashrc
.Here is similar version used on Travis CI:
检测操作系统和CPU类型并不容易可移植。 我有一个大约 100 行的
sh
脚本,可以在各种 Unix 平台上运行:我自 1988 年以来使用过的任何系统。关键元素是
uname -p 是处理器类型,但在现代 Unix 平台上通常
未知
。uname -m
将在某些 Unix 系统上给出“机器硬件名称”。/bin/arch
,如果存在,通常会给出处理器的类型。uname
不带参数将命名操作系统。最终,您将不得不考虑平台之间的区别以及您希望将它们做得有多好。例如,为了简单起见,我将
i386
视为i686
、任何“Pentium*
”和任何“AMD*Athlon*
”都为x86
。我的
~/.profile
在启动时运行一个脚本,该脚本将一个变量设置为指示 CPU 和操作系统组合的字符串。 我有基于平台特定的bin
、man
、lib
和include
目录。 然后我设置了大量的环境变量。 例如,重新格式化邮件的 shell 脚本可以调用 $LIB/mailfmt 等特定于平台的可执行二进制文件。如果您想走捷径,
uname -m
和简单的uname
会告诉您在许多平台上想知道的内容。 当你需要的时候添加其他东西。 (并使用case
,而不是嵌套if
!)Detecting operating system and CPU type is not so easy to do portably. I have a
sh
script of about 100 lines that works across a very wide variety of Unix platforms: any system I have used since 1988.The key elements are
uname -p
is processor type but is usuallyunknown
on modern Unix platforms.uname -m
will give the "machine hardware name" on some Unix systems./bin/arch
, if it exists, will usually give the type of processor.uname
with no arguments will name the operating system.Eventually you will have to think about the distinctions between platforms and how fine you want to make them. For example, just to keep things simple, I treat
i386
throughi686
, any "Pentium*
" and any "AMD*Athlon*
" all asx86
.My
~/.profile
runs an a script at startup which sets one variable to a string indicating the combination of CPU and operating system. I have platform-specificbin
,man
,lib
, andinclude
directories that get set up based on that. Then I set a boatload of environment variables. So for example, a shell script to reformat mail can call, e.g.,$LIB/mailfmt
which is a platform-specific executable binary.If you want to cut corners,
uname -m
and plainuname
will tell you what you want to know on many platforms. Add other stuff when you need it. (And usecase
, not nestedif
!)我建议使用这个完整的 bash 代码,
更多示例如下: https://github.com/coto/server-easy-install/blob/master/lib/core.sh
I recommend to use this complete bash code
more examples examples here: https://github.com/coto/server-easy-install/blob/master/lib/core.sh
我建议避免其中一些答案。 不要忘记,您可以选择其他形式的字符串比较,这将清除大多数变化或提供的丑陋代码。
一个这样的解决方案是一个简单的检查,例如:
它具有匹配任何版本的 Darwin 的额外好处,尽管它有版本后缀。 这也适用于人们可能期望的任何
Linux
变体。您可以在此处查看我的点文件中的一些其他示例
I would suggest avoiding some of these answers. Don't forget that you can choose other forms of string comparison, which would clear up most of the variations, or ugly code offered.
One such solution would be a simple check, such as:
Which has the added benefit of matching any version of Darwin, despite it's version suffix. This also works for any variations of
Linux
one may expect.You can see some additional examples within my dotfiles here
如果有人也有兴趣检测 WSL 与 WSL 版本 2,我会使用此方法。
这在 ZSH 和 BASH 中都有效。
更新:我还将其添加到我的脚本中,用于检测 M1 与普通 Mac。
This is what I use if anyone is interested in detecting WSL vs WSL version 2 as well.
This works in ZSH as well as BASH.
Update: I also added this to my script for detecting M1 vs a normal Mac.
或者
如果您想了解更多信息
or
if you want more information
尝试使用“uname”。 例如,在 Linux 中:“uname -a”。
根据手册页,uname 符合 SVr4 和 POSIX,因此它应该可以在 Mac OS X 和 上使用Cygwin 也是如此,但我无法确认这一点。
顺便说一句:这里 $OSTYPE 也设置为 linux-gnu :)
Try using "uname". For example, in Linux: "uname -a".
According to the manual page, uname conforms to SVr4 and POSIX, so it should be available on Mac OS X and Cygwin too, but I can't confirm that.
BTW: $OSTYPE is also set to
linux-gnu
here :)在 bash 中,使用
$OSTYPE
和$HOSTTYPE
,如文档所述; 这就是我所做的。 如果这还不够,并且即使uname
或uname -a
(或其他适当的选项)也没有提供足够的信息,那么总是有 config.guess 来自 GNU 的脚本项目,正是为此目的而制作的。In bash, use
$OSTYPE
and$HOSTTYPE
, as documented; this is what I do. If that is not enough, and if evenuname
oruname -a
(or other appropriate options) does not give enough information, there’s always the config.guess script from the GNU project, made exactly for this purpose.我在我的
.bashrc
中写了这些糖:所以我可以做类似的事情:
I wrote these sugars in my
.bashrc
:So I can do stuff like:
下面是一种利用 /etc/lsb-release 和 检测基于 Debian 和 RedHat 的 Linux OS 的方法/etc/os-release(取决于您使用的 Linux 风格)并根据它执行一个简单的操作。
Ubuntu Linux 的输出示例:
Below it's an approach to detect Debian and RedHat based Linux OS making use of the /etc/lsb-release and /etc/os-release (depending on the Linux flavor you're using) and take a simple action based on it.
Output example for Ubuntu Linux:
您可以使用以下内容:
然后您可以在脚本中使用操作系统变量。
You can use the following:
then you can use OS variable in your script.
我编写了 一个个人 Bash 库和脚本框架,它使用 GNU shtool 进行相当准确的平台检测。
GNU shtool 是一组非常可移植的脚本,其中包含“shtool platform”命令等有用的内容。 这是以下输出:
在几台不同的机器上:
正如您所看到的,这会产生非常令人满意的结果。 GNU shtool 有点慢,所以我实际上将平台标识存储和更新在我的脚本调用的系统上的文件中。 这是我的框架,所以对我有用,但你的里程可能会有所不同。
现在,您必须找到一种将 shtool 与脚本打包在一起的方法,但这并不是一个困难的练习。 您也可以随时依靠 uname 输出。
编辑:
我错过了 Teddy 关于 config.guess 的帖子(不知何故)。 这些脚本非常相似,但并不相同。 我个人也将 shtool 用于其他用途,并且它对我来说效果很好。
I wrote a personal Bash library and scripting framework that uses GNU shtool to do a rather accurate platform detection.
GNU shtool is a very portable set of scripts that contains, among other useful things, the 'shtool platform' command. Here is the output of:
on a few different machines:
This produces pretty satisfactory results, as you can see. GNU shtool is a little slow, so I actually store and update the platform identification in a file on the system that my scripts call. It's my framework, so that works for me, but your mileage may vary.
Now, you'll have to find a way to package shtool with your scripts, but it's not a hard exercise. You can always fall back on uname output, also.
EDIT:
I missed the post by Teddy about
config.guess
(somehow). These are very similar scripts, but not the same. I personally use shtool for other uses as well, and it has been working quite well for me.尝试这个:
try this:
这应该可以在所有发行版上安全使用。
这会产生类似这样的东西。
根据需要提取/分配给变量
注意:在某些设置上。 这也可能会给您带来一些可以忽略的错误。
This should be safe to use on all distros.
This produces something like this.
Extract/assign to variables as you wish
Note: On some setups. This may also give you some errors that you can ignore.
您可以使用以下 if 子句并根据需要扩展它:
You can use following if clause and expand it as needed:
我倾向于将 .bashrc 和 .bash_alias 保存在所有平台都可以访问的文件共享上。 这就是我在 .bash_alias 中克服问题的方法:
例如,我有一个 .bash_alias_Linux:
这样我可以将特定于平台的代码和可移植代码分开,您可以对 .bashrc 执行相同的操作
I tend to keep my .bashrc and .bash_alias on a file share that all platforms can access. This is how I conquer the problem in my .bash_alias:
And I have for example a .bash_alias_Linux with:
This way I keep platform specific and portable code separate, you can do the same for .bashrc
我在几个 Linux 发行版上尝试了上述消息,发现以下消息最适合我。 这是一个简短、精确的单词答案,也适用于 Windows 上的 Bash。
I tried the above messages across a few Linux distros and found the following to work best for me. It’s a short, concise exact word answer that works for Bash on Windows as well.
这会检查一堆
已知
文件来识别Linux发行版是否是Debian或Ubunu,然后它默认为$OSTYPE
变量。This checks a bunch of
known
files to identfy if the linux distro is Debian or Ubunu, then it defaults to the$OSTYPE
variable.我只关心Windows和Linux(特别是:Linux Ubuntu),但我想要更多关于它们的信息,而不是这里的主要答案< /a>.
因此,这是我对主要答案的扩展,以提供有关您正在运行的 Linux 或 Windows 版本的更多详细信息:
在 Git Bash 中运行时的示例输出(来自 Git For Windows) 在 Windows 上:
Linux Ubuntu 22.04 上的 Bash 终端的示例输出:
参考资料
Doxyfile_run_doxygen.sh
脚本https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles" rel="nofollow noreferrer">eRCaGuy_dotfiles 存储库。进一步发展
I just care about Windows and Linux (specifically: Linux Ubuntu), but I want more information about them than is provided by the main answer here.
So, here's my extension of the main answer to provide more details about which version of Linux or Windows you are running:
Example output when run in Git Bash (from Git For Windows) on Windows:
Example output from a Bash terminal on Linux Ubuntu 22.04:
References
Doxyfile_run_doxygen.sh
script in my eRCaGuy_dotfiles repo.Going further
执行以下操作有助于正确执行 ubuntu 的检查:
Doing the following helped perform the check correctly for ubuntu: