2

我正在编写一个 sh 文件来获取文件的修改时间。我希望 sh 文件适用于 Mac 和 Ubuntu。

我使用 /bin/sh 并将 #!/bin/sh 添加到 bash 文件的第一行。我想 /bin/sh 在两个操作系统上的行为应该相同。但事实并非如此。以下是差异的两个示例。

  1. 下面的脚本适用于 Mac,但不适用于 Ubuntu。

    modTime=$(stat -f "%m" -t "%s" $filepath)

  2. 下面的脚本适用于 Ubuntu,但不适用于 Mac。

    modTime=$(date +%s -r $filepath)

我的问题是:

  1. 为什么 /bin/sh 在 Mac 和 Ubuntu 上的行为不同?
  2. 如果要写跨平台的sh脚本,应该如何避免依赖平台的代码呢?
4

2 回答 2

7
  1. 为什么 /bin/sh 在 Mac 和 Ubuntu 上的行为不同?

因为它们都是不同的壳。ubuntu 上的 sh 是 dash shell,minix 上的 sh 是 ash shell,slackware 上的 sh 是 bash shell。而且由于 OSX 上的 sh 也不是太长,所以 bash shell

如果您想要相同的行为,请指定您的 shell...#!/bin/sh 虽然严格来说是 never-in-free-systems-implemented-bourne-shell,但通常是系统 shell,它可能因系统而异.. .use #!/bin/bash 从字面上说你的意思是 bash,使用 #!/bin/ksh 从字面上调用 korn-shell 等。

  1. 如果我想写跨平台的a sh脚本,应该如何避免依赖平台的代码呢?
  1. 正式:严格遵守 POSIX 规则,以便在任何符合 POSIX 的 shell 上运行

  2. 务实:为几乎任何系统上可用的一种外壳编写特定的(不包括微控制器和 SoC 或大熨斗和 sparc 站,bash 可用于大多数系统,但是有些系统不做 bash 所以 bash 是不是 100% 可移植性的最佳选择,但它绝对是(ab)使用最多的 ;-)

  3. 最佳便携性:作为 Ubuntu 用户的经验法则:如果它在 dash(ubuntu 的 /bin/sh)上运行,它几乎可以在任何东西(包括你的路由器、烤面包机和咖啡机)上运行。

  4. 最重要的是:user2719058是对的,OSX 不是 Linux 而是 BSD-UNIX,所以虽然它们可以运行相同的 shell,但命令的不同足以让编写一个万能的脚本变得非常困难。选择最好的 shell 不会改变这一点……因此,除非每个系统上的系统命令也符合 POSIX,否则统一脚本语言的价值被证明是非常有限的。

tl;dr:
统一的跨平台脚​​本是一个白日梦,因为跨系统二进制文件的差异阻止了这一点。

于 2013-11-13T02:50:30.117 回答
4

这不是 shell 的行为不同,而是您正在运行的命令。在 Ubuntu 上,这些来自 GNU 世界,在 MacOS 上,它们可能是一些 BSD 变体。这通常意味着,在 MacOS 上你的功能更少。:)

应该注意的是,这(我猜)也适用/bin/sh,但这不是您看到的破损的原因。

于 2013-11-13T02:01:33.857 回答