在任何符合POSIX标准的shell中获取自纪元以来的秒数

时间:2010-03-15 05:06:18

标签: shell scripting time posix

我想知道是否有办法在任何符合POSIX标准的shell中获取自UNIX纪元以来的秒数,而不使用像perl这样的非POSIX语言,或者使用像GNU awk的strftime函数这样的非POSIX扩展。

以下是我已经排除的一些解决方案......

  

date +%s //在Solaris上不起作用

之前我见过一些shell scripts suggested,它会解析date的输出,然后从格式化的格里高利历日期中获取秒数,但它们似乎没有像闰秒考虑在内。

GNU awk具有strftime函数,但在标准awk中不可用。

我可以编写一个调用time函数的小型C程序,但二进制文件将特定于特定的体系结构。

是否有使用POSIX兼容工具的跨平台方式?

我很想放弃并接受对perl的依赖,至少已广泛部署。

  

perl -e'print time'//作弊(非POSIX),但应该适用于大多数平台

3 个答案:

答案 0 :(得分:10)

以下是便携式/ POSIX解决方案:

PATH=`getconf PATH` awk 'BEGIN{srand();print srand()}'

C编译器或Perl不同,awk保证在符合POSIX的环境中出现。

工作原理:

  • PATH =`getconf PATH` 确保调用POSIX版本的awk如果它不是第一个一个在PATH

  • 根据POSIX standard: 的 函数srand([EXPR]) 如果省略expr,则将rand的种子值设置为expr或使用时间。应返回先前的种子值。

    第一个调用是省略参数,因此种子值设置为一天中的时间。第二个调用是返回那个时间,即自纪元以来的秒数。

    请注意,对于许多awk实现而不是GNU one(gawk),第一次调用不是必需的,因为函数已经首先返回了期望值。

    < / LI>

答案 1 :(得分:2)

仅出于教育目的,有点黑客攻击。但它就像你想象的POSIX一样: - )

#!/bin/sh
: > x
echo "ibase=8;$(pax -wx cpio x | cut -c 48-59)" | bc
rm x

让我们看看这是什么打印:

$ ./x.sh; date +%s
1314820066
1314820066

答案 2 :(得分:-3)

应该是相当可移植的,但需要对${.CURDIR};的写访问权,也许它可以被修改。

我没有将/tmp用于可执行文件,因为大多数人都/tmp安装了noexec。

无论如何都适用于FreeBSD。

#!/bin/sh

# Portably gets the date since epoch

bn=`basename $0`
prog=`mktemp /tmp/${bn}.mktime.XXXXXXX` || exit 1
>${prog}.c cat <<EOF
#include <stdio.h>
#include <time.h>
int main() {printf("%ju", time(NULL)); return 0; }
EOF

cc ${prog}.c
time=`./a.out`
rm ${prog} a.out

echo Time since epoch = $time seconds