我在 Jenkins Groovy 脚本化管道中有以下代码:
def time1 = sh(script: 'date -u +"%Y-%m-%dT%H:%M:%S+00:00"', returnStdout: true).trim()
def time1_sec = sh(script: 'date -d "$time1" +%s', returnStdout: true).trim()
sleep(time: 30, unit: 'SECONDS')
def time2 = sh(script: 'date -u +"%Y-%m-%dT%H:%M:%S+00:00"', returnStdout: true).trim()
def time2_sec = sh(script: 'date -d "$time2" +%s', returnStdout: true).trim()
控制台日志显示
time1_sec
和 time2_sec
都获得相同的值,这意味着无论我将哪个日期/时间数据转换为秒,它都会返回 1709164800
。
11:35:12 [Pipeline] sh
11:35:13 + date -u +%Y-%m-%dT%H:%M:%S+00:00
11:35:13 [Pipeline] sh
11:35:13 + date -d +%s
11:35:13 [Pipeline] sleep
11:35:13 Sleeping for 30 sec
11:35:43 [Pipeline] sh
11:35:44 + date -u +%Y-%m-%dT%H:%M:%S+00:00
11:35:44 [Pipeline] sh
11:35:45 + date -d +%s
11:35:45 [Pipeline] echo
11:35:45 time1 : 2024-02-29T16:35:13+00:00
11:35:45 [Pipeline] echo
11:35:45 time2 : 2024-02-29T16:35:44+00:00
11:35:45 [Pipeline] echo
11:35:45 time1_sec: 1709164800
11:35:45 [Pipeline] echo
11:35:45 time2_sec: 1709164800
我在 Linux 终端中使用了相同的 shell 命令,得到了预期的结果:
#!/bin/bash
# Script name: date-time-2-seconds.sh
time1=$(date -u +"%Y-%m-%dT%H:%M:%S+00:00")
time1_sec=$(date -d "$time1" +%s)
sleep 30
time2=$(date -u +"%Y-%m-%dT%H:%M:%S+00:00")
time2_sec=$(date -d "$time2" +%s)
echo "time1 : ${time1}"
echo "time2 : ${time2}"
echo "time1_sec: ${time1_sec}"
echo "time2_sec: ${time2_sec}"
$ ./date-time-2-seconds.sh
time1 : 2024-02-29T16:52:58+00:00
time2 : 2024-02-29T16:53:28+00:00
time1_sec: 1709225578
time2_sec: 1709225608
我在 Jenkins Groovy 脚本中做错了什么?
单引号字符串中不会发生字符串插值。您将文字字符串
date -d "$time1" +%s
传递到 shell,其中未定义名为 time1
的变量。
相反,您需要在
双引号字符串中扩展 Groovy 变量
time1
,以便 shell 可以看到结果,例如 date -d "2024-02-29T16:35:13+00:00" +%s
def time1 = sh(script: 'date -u +"%Y-%m-%dT%H:%M:%S+00:00"', returnStdout: true).trim()
def time1_sec = sh(script: "date -d '${time1}' +%s", returnStdout: true).trim()
sleep(time: 30, unit: 'SECONDS')
def time2 = sh(script: 'date -u +"%Y-%m-%dT%H:%M:%S+00:00"', returnStdout: true).trim()
def time2_sec = sh(script: "date -d '${time2}' +%s", returnStdout: true).trim()
请注意,在这种情况下,shell 不关心单引号和双引号之间的差异,因为
time1
和 time2
的值不需要 shell 进行插值。