23

我正在编写一个需要进行一些日期字符串操作的 shell 脚本。该脚本应该在尽可能多的 *nix 变体中工作,因此我需要处理机器可能具有 BSD 或 GNU 版本日期的情况。

测试操作系统类型的最优雅的方法是什么,以便我可以发送正确的日期标志?

编辑: 澄清一下,我的目标是使用日期的相对日期计算工具,这些工具在 BSD 和 GNU 中似乎不同。

BSD 示例

date -v -1d

GNU 示例

date --date="1 day ago"
4

4 回答 4

17

您想检测date您正在使用的命令版本,不一定是操作系统版本。

GNU Coreutilsdate命令接受该--version选项;其他版本不:

if date --version >/dev/null 2>&1 ; then
    echo Using GNU date
else
    echo Not using GNU date
fi

但正如 William Pursell 建议的那样,如果可能的话,您应该只使用两者共有的功能。

(我认为可用于 GNU date 的选项几乎是可用于 BSD 版本的选项的超集;如果是这种情况,那么假定 BSD 版本的代码应该适用于 GNU 版本。)

于 2012-01-05T19:13:03.530 回答
11

使用便携式标志。该标准可在此处获得

对于打印相对日期的特定问题,使用 perl 可能比使用日期更容易:

perl -E 'say scalar localtime(time - 86400)'

(请注意,此解决方案在 23 或 25 小时内完全失败,但许多 perl 解决方案可用于解决该问题。请参阅 perl 常见问题解答。)

但是您当然可以使用 Keith 的想法的变体并执行以下操作:

if date -v -1d > /dev/null 2>&1; then
  DATE='date -v -1d'
else
  DATE='date --date="1 day ago"'
fi
eval "$DATE"

要不就

DATE=$(date -v -1d 2> /dev/null) || DATE=$(date --date="1 day ago")

另一个想法是定义一个要使用的函数:

if date -v -1d > /dev/null 2>&1; then
    date1d() { date -v -1d; }
else
    date1d() { date --date='1 day ago'; }
fi
于 2012-01-05T19:01:11.610 回答
1

只是回答你的问题,可能“uname -o”就是你想要的。就我而言,它是“GNU/Linux”。您可以自己决定检测操作系统类型是否毫无价值。

于 2012-01-05T20:44:20.033 回答
1

建议使用基于特征的检测,而不是基于操作系统或平台的检测。

以下示例代码显示了它是如何工作的:

if is-compatible-date-v; then
    date -v -1d
elif is-compatible-date-d; then
    date --date="1 day ago"
fi
function is-compatible () {
    "$@" >/dev/null 2>&1
}

function is-compatible-date-v () {
    is-compatible date -v +1S
}

function is-compatible-date-d () {
    is-compatible date -d '1 second'
}

我确实需要编写一些 shellcode 来处理date,并希望代码能够在 BSD 和 GNU 版本的date.

我最终得到了一组脚本,它们为 BSD 和 GNU 版本的date.

例子:

Follow 命令将输出比 晚 21 天的日期,2008-10-10它适用于 BSD 和 GNU 版本的date.

$ xsh x/date/adjust +21d 2008-10-10
2008-10-31

脚本可以在以下位置找到:

它是一个名为xsh-lib/core. 要使用它们,您需要 reposxshxsh-lib/core,我在下面列出它们:

希望这能帮助有同样需要的人。

于 2021-01-30T11:47:24.450 回答