Docker Alpine Linux 容器上的“date -d”命令失败

Docker Alpine Linux 容器上的“date -d”命令失败

我建造了阿尔卑斯Linux在一个Docker容器使用以下 Dockerfile:

FROM alpine:3.2
RUN apk add --update jq curl && rm -rf /var/cache/apk/*

构建成功运行:

$ docker build -t collector .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon 
Step 0 : FROM alpine:3.2
3.2: Pulling from alpine
8697b6cc1f48: Already exists 
alpine:3.2: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:eb84cc74347e4d7c484d566dec8a5eef82bab1b78308b92cda559bcff29c27cc
Status: Downloaded newer image for alpine:3.2
 ---> 8697b6cc1f48
Step 1 : RUN apk add --update jq curl && rm -rf /var/cache/apk/*
 ---> Running in 888571296e79
fetch http://dl-4.alpinelinux.org/alpine/v3.2/main/x86_64/APKINDEX.tar.gz
(1/11) Installing run-parts (4.4-r0)
(2/11) Installing openssl (1.0.2a-r1)
(3/11) Installing lua5.2-libs (5.2.4-r0)
(4/11) Installing lua5.2 (5.2.4-r0)
(5/11) Installing ncurses-terminfo-base (5.9-r3)
(6/11) Installing ncurses-widec-libs (5.9-r3)
(7/11) Installing lua5.2-posix (33.3.1-r2)
(8/11) Installing ca-certificates (20141019-r2)
(9/11) Installing libssh2 (1.5.0-r0)
(10/11) Installing curl (7.42.1-r0)
(11/11) Installing jq (1.4-r0)
Executing busybox-1.23.2-r0.trigger
Executing ca-certificates-20141019-r2.trigger
OK: 9 MiB in 26 packages
 ---> 7625779b773d
Removing intermediate container 888571296e79
Successfully built 7625779b773d

无论如何,当我运行时date -d它失败了:

$ docker run -i -t collector sh
/ # date -d yesterday
date: invalid date 'yesterday'
/ # date -d now
date: invalid date 'now'
/ # date -d next-month
date: invalid date 'next-month'

而其余选项似乎运行正常:

/ # date 
Sat May 30 18:57:24 UTC 2015
/ # date +"%A"
Saturday
/ # date +"%Y-%m-%dT%H:%M:%SZ"
2015-05-30T19:00:38Z

答案1

BusyBox/Alpine 版本的 date 不支持-d选项,即使 Ubuntu 版本以及其他更胖的发行版中的帮助完全相同。

此外,“容器化”也不会遗漏任何东西。

要使用-d选项,您只需添加coreutils包:

$ cat Dockerfile.alpine-coreutils
FROM alpine:3.2
RUN apk add --update coreutils && rm -rf /var/cache/apk/*


$ docker build -t alpine-coreutils - <  Dockerfile.alpine-coreutils
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon 
Step 0 : FROM alpine:3.2
3.2: Pulling from alpine
8697b6cc1f48: Already exists 
alpine:3.2: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:eb84cc74347e4d7c484d566dec8a5eef82bab1b78308b92cda559bcff29c27cc
Status: Downloaded newer image for alpine:3.2
 ---> 8697b6cc1f48
Step 1 : RUN apk add --update coreutils && rm -rf /var/cache/apk/*
 ---> Running in 694fa5cb271c
fetch http://dl-4.alpinelinux.org/alpine/v3.2/main/x86_64/APKINDEX.tar.gz
(1/3) Installing libattr (2.4.47-r3)
(2/3) Installing libacl (2.2.52-r2)
(3/3) Installing coreutils (8.23-r0)
Executing busybox-1.23.2-r0.trigger
OK: 12 MiB in 18 packages
 ---> a7d9116a00ee
Removing intermediate container 694fa5cb271c
Successfully built a7d9116a00ee


$ docker run -i -t alpine-coreutils sh
/ # date -d last-week
Sun May 24 09:19:34 UTC 2015
/ # date -d yesterday 
Sat May 30 09:19:46 UTC 2015
/ # date 
Sun May 31 09:19:50 UTC 2015

与 Debian 标准相比,图像大小将增加一倍,但直到 11.47 MB​​,大小少了一个数量级:

$ docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
alpine-coreutils           latest              a7d9116a00ee        2 minutes ago       11.47 MB
alpine                     3.2                 8697b6cc1f48        2 days ago          5.242 MB
debian                     latest              df2a0347c9d0        11 days ago         125.2 MB

感谢安迪·辛恩: https://github.com/gliderlabs/docker-alpine/issues/40#issuecomment-107122371

克里斯托弗·霍雷尔:https://github.com/docker-library/official-images/issues/771#issuecomment-107101595

答案2

busybox date支持一个-D选项,该选项(类似于zsh'sstrftime但与 GNU 相反date)为您提供了一个界面,strptime()您可以在其中解析任何格式的日期(尽管不是相对日期)(ast-opendateksh93'sprintf也有自定义输入格式的方法)。

Wherebusybox是针对 C 库实现构建的,strptime()并且strftime()支持非标准%s标志,您可以这样做:

date -D %s -d "$(($(date +%s) - 86400))"

然而,在 alpine Linux 使用的 musl C 库中,strftime()支持%sstrptime()不支持。不过作为 busybox 来说没关系date,就像 GNUdate支持@epochtime日期规范一样,所以你可以这样做:

date -d "@$(($(date +%s) - 86400))"

这将为您提供 86400 秒前的日期,而不存在 GNU 的歧义dateyesterday是 86400 前,还是昨天的同一时间?如果昨天因为时钟改变而没有这样的时间怎么办?夏令时?)。

该语法也应该适用于 GNU date

使用 ast-open 的date(或 ksh93 的printf '%(%c)T'),您可以使用:

date -d "#$(($(date +%s) - 86400))"

反而。

请注意,如果您想报告 UTC (Zulu) 时间,则应使用 UTC (Zulu) 时间,TZ=UTC0 date否则date -u您将获得系统/用户时区的时间。

答案3

编辑:我在 Alpine:3.2 上测试了这个命令

要从当天减去 24 小时,您可以运行:

# date
Fri Jul 10 13:08:56 UTC 2020

# date -d "-24:00:00"
Thu Jul  9 00:00:00 UTC 2020

您还可以使用以下方法添加到当前日期:

# date -d "+24:00:00"
Sat Jul 11 00:00:00 UTC 2020

希望这可以帮助

答案4

如果您需要时区转换,coreutils这是不够的。
你也会需要tzdata

像这样的命令TZ='America/Los_Angeles' date不起作用,TZvar 会被忽略。时区转换开始正常工作
后。apk add tzdata

相关内容