如何在shell脚本中检测BSD与GNU版本的日期

时间:2012-01-05 18:35:49

标签: shell date gnu bsd

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

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

修改 为了澄清,我的目标是使用日期的相对日期计算工具,这些工具在BSD和GNU中看起来不同。

BSD示例

date -v -1d

GNU示例

date --date="1 day ago"

4 个答案:

答案 0 :(得分:13)

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

GNU Coreutils date命令接受--version选项;其他版本没有:

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

但正如William Pursell所说,如果可能的话,你应该只使用两者共有的功能。

(我认为 GNU日期可用的选项几乎是BSD版本可用的选项;如果是这种情况,那么假定BSD版本的代码应该与GNU版本一起使用。)

答案 1 :(得分:8)

使用便携式标志。该标准可用 here

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

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

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

但是你当然可以使用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")

答案 2 :(得分:1)

要回答你的问题,可能“uname -o”就是你想要的。就我而言,它是“GNU / Linux”。如果检测到os类型没有价值,你可以自己决定。

答案 3 :(得分:0)

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

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

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,并希望代码能够在 date 的 BSD 和 GNU 版本上运行。

我最终得到了一组脚本,它们为 date 的 BSD 和 GNU 版本提供了统一的接口。

示例:

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

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

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

它是名为 xsh-lib/core 的库的一部分。要使用它们,您需要存储库 xshxsh-lib/core,我将它们列在下面:

希望这能帮助有相同需求的人。