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

发布于 2024-12-25 06:02:20 字数 352 浏览 4 评论 0原文

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

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

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

BSD 示例

date -v -1d

GNU 示例

date --date="1 day ago"

I am writing a shell script that needs to do some date string manipulation. The script should work across as many *nix variants as possible, so I need to handle situations where the machine might have the BSD or the GNU version of date.

What would be the most elegant way to test for the OS type, so I can send the correct date flags?

EDIT:
To clarify, my goal is to use date's relative date calculation tools which seem distinct in BSD and GNU.

BSD example

date -v -1d

GNU example

date --date="1 day ago"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

森罗 2025-01-01 06:02:20

您想要检测您正在使用的 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 版本。)

You want to detect what version of the date command you're using, not necessarily the OS version.

The GNU Coreutils date command accepts the --version option; other versions do not:

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

But as William Pursell suggests, if at all possible you should just use functionality common to both.

(I think the options available for GNU date are pretty much a superset of those available for the BSD version; if that's the case, then code that assumes the BSD version should work with the GNU version.)

对岸观火 2025-01-01 06:02:20

使用便携式旗帜。该标准可在 此处

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

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")

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

if date -v -1d > /dev/null 2>&1; then
    date1d() { date -v -1d; }
else
    date1d() { date --date='1 day ago'; }
fi

Use portable flags. The standard is available here

For the particular problem of printing a relative date, it is probably easier to use perl than date:

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

(note that this solution utterly fails on 23 or 25 hour days, but many perl solutions are available to address that problem. See the perl faq.)

but you could certainly use a variation of Keith's idea and do:

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

or just

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

Another idea is to define a function to use:

if date -v -1d > /dev/null 2>&1; then
    date1d() { date -v -1d; }
else
    date1d() { date --date='1 day ago'; }
fi
流年里的时光 2025-01-01 06:02:20

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

以下示例代码展示了它的工作原理:

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 命令将输出比 2008-10-10 晚 21 天的日期,并且它适用于 BSD 和 GNU 版本的 date

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

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

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

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

It is recommended to use feature-based defection rather than the os-based or platform-based detection.

Following sample code show how it works:

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'
}

I was having the exact need to writing some shellcode to deal with date, and hoping the code be able to run on both BSD and GNU version of date.

I end up with a set of scripts that provides a uniform interface for both BSD and GNU version of date.

Example:

Follow command will output a date that is 21 days later than 2008-10-10, and it works with both BSD and GNU version of date.

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

The scripts can be found at:

It's a part of a library called xsh-lib/core. To use them you need both repos xsh and xsh-lib/core, I list them below:

Hope this will help people with the same need.

绻影浮沉 2025-01-01 06:02:20

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

To just answer your question, probably "uname -o" is what you want. In my case it's "GNU/Linux". You can decide for yourself if detecting the os type is worthless or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文