【问题标题】:linux shell date questionlinux shell日期问题
【发布时间】:2009-10-29 15:13:43
【问题描述】:
shell>/bin/date -d "091029 20:18:02" +%s
1256827682

同样我创建了 shell 脚本:

#My.sh
myDate=`date +'%y%m%d_%H%M%S'`
myDate1=`echo $myDate | sed 's/_/ /g'`
myDate2=`echo $myDate1 | sed 's/\([0-9][0-9][0-9][0-9][0-9][0-9]\) \([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)/\/bin\/date -d "\1 \2:\3:\4" +%s/'`
print $myDate2
`$myDate2`

但它不执行上面的命令。为什么?

【问题讨论】:

  • 检查权限并确保其可执行
  • mobruleHai Vu 的答案正是您所需要的。

标签: linux shell date scripting


【解决方案1】:

最后一行中的反引号执行命令,然后执行该命令的输出,这可能不是你想要做的——当我运行它时,我得到了输出 @987654321 @。去掉最后一行的反引号,这样它就可以说

    $myDate2

【讨论】:

  • eval $myDate2 成功了。输出=eval $myDate2echo $output
【解决方案2】:

除了上面的解决方案,我想提供助手到myDate2:

$ myDate=$(date +'/bin/date -d "%y%m%d %H:%M:%S" +%%s')
$ echo $myDate
/bin/date -d "091029 09:06:29" +%s

【讨论】:

  • 这好多了。所有那些sed 的回旋都是完全没有必要的。
  • 我什至没有看脚本真正应该实现的目标;只是在实现它的机制上。
  • @Jonathan Leffler:我完全理解你做了什么。这篇文章是对您解决方案的补充。
【解决方案3】:

符号:

`$myDate2`

扩展 $myDate2 并执行命令(我会回到为什么会出现问题),然后捕获输出 - 并尝试运行输出。

你要找的是eval:

eval $myDate2

处理引号很棘手 - eval 通常是答案的一部分。当您使用内部引号构建字符串时,您需要使用 eval 让 shell 将引号重新组合在一起。

我拥有的一个非常有用的工具是一个名为 al 的程序 - 用于参数列表。

#include <stdio.h>
int main(int argc, char **argv)
{
    while (*++argv != 0)
        puts(*argv);
    return(0);
}

它将每个单独的参数打印在单独的行上。当我看到你在做什么时,这几乎是我做的第一件事。

myDate=`date +'%y%m%d_%H%M%S'`
myDate1=`echo $myDate | sed 's/_/ /g'`
myDate2=`echo $myDate1 | sed 's/\([0-9][0-9][0-9][0-9][0-9][0-9]\) \([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)/\/bin\/date -d "\1 \2:\3:\4" +%s/'`
print $myDate2
#`$myDate2`
al $myDate2
eval al $myDate2
eval $myDate2

由此产生的跟踪输出是:

+ date +%y%m%d_%H%M%S
+ myDate=091029_082546
+ sed 's/_/ /g'
+ echo 091029_082546
+ myDate1='091029 082546'
+ sed 's/\([0-9][0-9][0-9][0-9][0-9][0-9]\) \([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)/\/bin\/date -d "\1 \2:\3:\4" +%s/'
+ echo 091029 082546
+ myDate2='/bin/date -d "091029 08:25:46" +%s'
+ print /bin/date -d '"091029' '08:25:46"' +%s
/bin/date -d "091029 08:25:46" +%s
+ al /bin/date -d '"091029' '08:25:46"' +%s
/bin/date
-d
"091029
08:25:46"
+%s
+ eval al /bin/date -d '"091029' '08:25:46"' +%s
+ al /bin/date -d '091029 08:25:46' +%s
/bin/date
-d
091029 08:25:46
+%s
+ eval /bin/date -d '"091029' '08:25:46"' +%s
+ /bin/date -d '091029 08:25:46' +%s
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... 
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]

请注意,当我运行 'al $myDate2' 时,日期字符串是如何拆分为两个参数的,但是当我运行 'eval al $myDate2' 时,字符串是一个参数 - 根据需要。我在 MacOS X 上进行测试,其中 data 命令不接受您提供的日期字符串格式 - 这是一个完全独立的问题。但是要治愈字符串需要'eval'。


我什至没有解决 shell 脚本试图做什么的问题。

我从 Hai Vu 的回答中得知,我们确实是在从纪元开始以秒为单位的当前时间之后;我可以看到那可能是什么。

在 MacOS X 上,这是很容易获得的:

date +'%s'

(实际上不需要单引号)。 MacOS X 手册页还包括示例:

      date -j -f "%a %b %d %T %Z %Y" "`date`" "+%s"

这似乎有点令人费解 - 但可以让您找到日期命令先前给出的任何日期的纪元以来的秒数 - 或将在未来某个时间给出的日期(通过替换反引号日期与前一个字符串)。

大约在一年前,我编写了程序“systime”以将当前时间打印为纪元过去的秒数,还编写了一个程序“timestamp”将这些值转换回格式化的日期——因为没有标准'date' 命令的版本当时支持这种机制(在 C 标准成为标准之前,因此在 strftime() 广泛可用之前)。我还有一个程序“strptime”,用于将格式化的日期转换为时间戳。嗯,很高兴知道标准程序现在可以做到这一点。

但是,我注意到 MacOS 的“日期”命令是 POSIX 标准版本的超集;我怀疑 Linux (GNU) 的“日期”命令是 POSIX 标准的不同超集,等等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多