【问题标题】:Bash Script - Comparing last modified dates [duplicate]Bash 脚本 - 比较上次修改日期 [重复]
【发布时间】:2020-07-29 14:46:16
【问题描述】:

尝试将date 输出匹配到与curl 上次修改日期相同的格式,即:Last-Modified: Thu, 16 Apr 2020 08:14:26 GMT,使用下面脚本中的Awk 过滤器是16 Apr 2020 09:27:51。本地文件的最后修改日期将与远程文件的最后修改日期进行比较。这个脚本感觉很不稳定,我正在考虑比较文本文件中的日期字符串,而不是依赖 Http 标头反馈?

我知道 curl 中的 -z 选项,但我想通过 if 语句给用户选项,它不能完全自动化更新过程,需要用户(管理员)输入。

http 标头

HTTP/1.1 200 OK
Server: nginx
Date: Thu, 16 Apr 2020 08:43:13 GMT
Content-Length: 0
Connection: keep-alive
Last-Modified: Thu, 16 Apr 2020 08:14:26 GMT
Expires: Thu, 16 Apr 2020 08:44:13 GMT
Cache-Control: max-age=60
X-Cache-Status: MISS
X-Backend-ip: x.0.172.195
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Pragma: public
Cache-Control: public
Vary: Accept-Encoding
Accept-Ranges: bytes

脚本:

#!/bin/bash

local_file="/Users/usr/Desktop/file"
remote_file="www.someurl.com/file"


# current output format: 16 Apr 2020 08:14:26
remote_last_modified_date="$(curl -sI ${remote_file} | grep -E "Last-Modified:" | awk '{print $3,$4,$5,$6}' )"

# current output format: Thu Apr 9 18:15:30 SAST 2020  
local_last_modified_date="$(date -r "$local_file" )" 


parsed_remote_last_modified_date="$(date  +%s -d "$remote_last_modified_date")"  
parsed_local_last_modified_date="$(date -r "$local_file")"


  echo "local "$parsed_local_last_modified_date""
   echo "remote "$parsed_remote_last_modified_date""


if [ ${parsed_local_last_modified_date} -lt 
${parsed_remote_last_modified_date} ] ; then


    echo "A new version is available"

else

    echo "latest update already installed"
fi

错误:

date: illegal time format
usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... 
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]

【问题讨论】:

  • 感谢分享您尝试过的代码,继续努力。除了努力分享,我们还鼓励用户添加输入示例和预期输出示例,因此请在您的问题中添加相同内容并让我们知道。
  • 您是否尝试更改日期格式date '+%a, %d %b %T GMT' 它将返回您所说的Thu, 16 Apr 2020 08:14:26 GMT Last-Modified
  • 它给出了同样的错误,我在 local_last_modified_date 变量中看不到语法错误。尝试了 date -rf 选项 - 也没有用。
  • 试试local_last_modified_date="$( date -r "${local_file}" '+%D %T' )
  • 演示:$date -r "file.txt" '+%D %T' --> 04/16/20 11:36:19

标签: regex bash shell awk


【解决方案1】:

我在不使用 shell 的 date 命令的情况下重写了脚本,该命令不能跨 MacOS 和 GNU Linux 移植。我改用ls,希望这个命令实际上是可移植的。请检查:

#!/bin/bash

## variables commented out since we don't have access to theirs values: 
#remote_file="www.someurl.com/file"
#remote_last_modified_date="$(curl -sI ${remote_file} | grep -E "Last-Modified:" | awk '{print $3,$4,$5,$6}' )"


## let's suppose we get next result into our variables:
local_file="test"
remote_last_modified_date="16 Apr 2020 08:14:26"

## we don't use the date command, not portable across MacOS and GNU Linux
## we use ls command with the option --time-style instead

## rewrite dates to allow comparison in format +"%Y-%m-%d_%H:%M:%S"
local_sortable_date=$(ls -l --time-style=+"%Y-%m-%d_%H:%M:%S" "$local_file"| cut -d ' ' -f 6)

remote_year=${remote_last_modified_date:7:4}
remote_month_name=${remote_last_modified_date:3:3}
remote_month=$(echo $remote_month_name | 
  sed 's/Jan/01/;s/Feb/02/;s/Mar/03/;s/Apr/04/;s/May/05/;s/Jun/06/;
    s/Aug/08/;s/Sep/09/;s/Oct/10/;s/Nov/11/;s/Dec/12/')
remote_day=${remote_last_modified_date:0:2}
remote_time=${remote_last_modified_date:12:8}

remote_sortable_date=${remote_year}-${remote_month}-${remote_day}_$remote_time

if [[ $remote_sortable_date > $local_sortable_date ]] ; then
  echo "A new version is available"
  set of commands
else
  echo "latest update already installed"
fi

【讨论】:

  • 非常感谢您的所有意见 - 它奏效了。安装gnu核心实用程序后,我唯一需要cgange的是“ls”到“gls”。这适用于 ubuntu 吗?
  • so mac 可以比较这种格式: 2020-04-16_08:14:26 ,我很高兴。
  • 命令gls在Linux Ubuntu上不存在,但你可以定义一种别名:[ -x /bin/ls ] && LS=ls || LS=gls并发出命令$LS而不是lsgls,根据有无可执行文件/bin/ls.
  • 只有一件事我不明白。这些数字如何在变量之后加起来,我可以看到它在做什么(提取),例如 remote_year=${remote_last_modified_date:7:4} ?
  • 这是选择子字符串的 bash 方式:${var:7:4} 表示从位置 7 开始的$var 的子字符串(从第一个位置开始的第八个字符是0)和@987654334 @ 字符长。
【解决方案2】:

试试:

#!/bin/bash

## variables commented out since we don't have access to theirs values: 
#remote_file="www.someurl.com/file"
#remote_last_modified_date="$(curl -sI ${remote_file} | grep -E "Last-Modified:" | awk '{print $3,$4,$5,$6}' )"


## let's suppose we get next result into our variables:
local_file="test"
remote_last_modified_date="16 Apr 2020 08:14:26"

## let's compute timestamps
remote_last_modified_timestamp=$(date --date="$remote_last_modified_date" +"%s")
local_last_modified_timestamp=$(date +'%s' -r "${local_file}")

if [ $local_last_modified_timestamp -lt $remote_last_modified_timestamp ] ; then
  echo "A new version is available"
  set of commands
else
  echo "latest update already installed"
fi

【讨论】:

  • 谢谢 Pierre,我仍然收到非法时间格式错误。日期:非法选项 -- - 用法:日期 [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format] date:非法时间格式用法:date [-jnRu] [-d dst] [-r seconds] [-t西] [-v[+|-]val[ymwdHMS]] ... [-f fmt 日期 | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format] ./version_2.sh: line 18: [: : integer expression expected latest update already installed wolfs-MacBook:version-检查狼$
  • 当我在我的版本上使用 lt 运算符时,我得到本地 LMD 1970 年 1 月 1 日 02:00:00 远程 LMD 2020 年 4 月 16 日 08:14:26 ./version.sh: 第 15 行:[ :1970 年 1 月 1 日 02:00:00:整数表达式预期已安装最新更新
  • 第 15 行:如果 [ "${local_last_modified_date}" -lt "${remote_last_modified_date}" ] ;那么
  • 忽略LMD部分,这只是我输入的测试回声。
  • 我担心我们没有相同的日期功能。你在哪个系统上?我想MacOS。我在 Linux 上。 usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format] 的消息看起来不像我在系统上收到的消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-23
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多