【发布时间】:2014-09-17 23:07:15
【问题描述】:
我有一个 shell 脚本,我想在多个都支持 bash 的平台上运行。我的问题是某些命令在 Linux、FreeBSD、OS X 和 Cygwin 上的行为不同。
到目前为止我的想法是:
- 在主脚本中为所有特定于操作系统的操作创建函数的默认实现,然后检查
$OSTYPE和source一个特定于实现的文件,该文件(可选)替换行为不同的命令。如果我这样做,我应该如何处理带有多个参数的命令?传递给函数的四个位置参数并不是最简洁的方法。 - 将所有实现放在我的脚本中,每个都在名称中添加一个词缀,检查
$OSTYPE并创建一个OPSUFFIX变量,然后为每个操作调用operation$OPSUFFIX。 -
./configure魔术? - 迁移到 Python 之类的东西——也许是最明智的,但需要最多的代码更改。如果这是一个惯用的 init 脚本,那么这不是一个选项。
【问题讨论】:
-
如果你想要真正跨平台的东西,那么你需要从脚本迁移到编程——有许多语言从代码中抽象出操作系统实现; Python、Ruby、Java 仅举几例。如果您让 Windows 用户安装 Cygwin (eew),那么让他们安装其他其中之一并不是什么大问题。
-
许多标准命令的大部分操作都具有标准化的行为。如果您可以设法留在该区域内(并且可以断言
bash,这不一定是您可以合理断言的东西),您通常可以编写一个大部分可移植的脚本。 -
@BoristheSpider 在自己的工作流程中使用 Cygwin 或 UWin 没有错,尤其是在跨平台使用脚本时。我不知道没有 Cygwin 的人是怎么过的。
-
POSIX(便携式操作系统接口)正是出于这个原因而定义的。如果您坚持使用 POSIX 规范定义的命令,并且只使用 POSIX 定义的选项,那么您的脚本将与预期的一样可移植。此外,您可能会考虑在 POSIX
sh而不是bash中编写脚本,这样无论存在哪个(与 POSIX 兼容的)shell,脚本都可以工作。 -
这在很大程度上取决于您想要在脚本中执行的操作(例如:文件位置、名称、行为)。我经常这样做(AIX/SUN/Linux),不幸的是我创建了一个特定行为列表并根据操作系统/版本重载脚本。查看 sed 的不同用途,具体取决于版本和操作系统,或者只是有时需要换行符 (SUN) 的管道行为,而“相同”外壳中的其他操作系统则不需要。
标签: bash shell cross-platform