【问题标题】:ksh epoch to datetime formatksh 纪元到日期时间格式
【发布时间】:2016-11-02 17:47:19
【问题描述】:

我有一个脚本可以找到任何用户密码的过期日期。脚本可以以秒(纪元)为单位找到过期日期,但无法将其转换为日期时间格式。

#!/usr/bin/ksh

if (( ${#} < 1 )) ; then
   print "No Arguments"
   exit
fi

lastupdate=`pwdadm -q $1|awk '{print $3;}'`
((lastupdate=$lastupdate+0))
maxagestr=`lsuser -a maxage $1`
maxage=${maxagestr#*=}
let maxageseconds=$maxage*604800
expdateseconds=$(expr "$maxageseconds" + "$lastupdate")
((expdateseconds=$expdateseconds+0))
expdate=`perl -le 'print scalar(localtime($expdateseconds))'`
echo $expdateseconds
echo $expdate

在此脚本中,expdateseconds 值为 true。如果我键入 expdateseconds 的值作为 localtime() 函数的参数,该函数会以 datetime 格式显示日期。

但是,如果我键入 $expdateseconds 变量,该函数将无法正常工作并始终返回 01.01.1970。

如何输入变量作为 localtime() 函数的参数?

【问题讨论】:

  • 在你的 perl 脚本周围使用 dbl 引号?另外,看看你的date 命令提供了哪些选项,它是一个要加载的小程序(man date)。祝你好运。

标签: perl datetime ksh aix epoch


【解决方案1】:

Shell 变量不在单引号内展开。因此,在您的代码中,perl 不是“看到”shell 变量,而是看到一个未初始化的 perl 变量,其值默认为零。 Shell 变量 在双引号内展开,所以在这种情况下,您需要做的就是:

expdate=`perl -le "print scalar(localtime($expdateseconds))"`

【讨论】:

  • 谢谢。我是这个领域的新手。由于我的声誉,我无法给出有用的答案。抱歉。
  • 在这样的单行中,我会使用~~ 而不是scalar 并去掉括号:perl -le "print ~~localtime $expdateseconds"。在现代 perl 上,您还可以使用 -Esay 代替 -leprint
【解决方案2】:

正如@JeffY 所说,您的问题是引号。你也可以不使用 perl(假设你的 date 命令是 GNU 版本):

expdate=`date -d @$expdateseconds`

虽然,由于您使用的是 ksh - 实际上,任何现代 POSIX shell - 我建议您避免使用 `...`,这可能会导致与引用混淆的行为,并使用 $(...)反而。

expdate=$(date -d @$expdateseconds)

这不是 codereview,但我有一些关于您的脚本的其他提示。通常的规则是将错误消息(如“无参数”)发送到标准错误而不是标准输出(使用print -u2),并在出现使用错误时以非零值(通常为 1)退出。

每当将参数传递给命令时,例如pwadm -q $1,除非你双引号参数:pwadm -q "$1",否则你冒着有趣的字符把事情搞砸的风险。

在您的算术运算中,let((expr 出现了奇怪的混合。我建议您使用 typeset -ivarname 声明所有数值变量,并使用 ((...)) 进行所有算术运算。在((...)) 中,您不必担心会弄乱全局(例如,如果当前目录中有一个名为a=b.c 的文件,let a=b*c 将扩展为语法错误; (( a=b*c )) 不会)。您也不需要在变量上加上美元符号(这只会让 shell 将它们转换为字符串,然后再次解析它们的数值),或者向它们添加 0 以确保它们是数字。

【讨论】:

  • 我来不及回答,但非常感谢。我不能给出积极的观点,很抱歉,但是当我可以的时候,我会的。
【解决方案3】:

没有必要既不使用awk 也不使用perl。例如:

#!/usr/bin/ksh93

[[ -z $1 ]] && print -u2 "No Arguments" && exit 1

typeset -i LASTUPDATE  S

X=( ${ pwdadm -q "$1" ; } )
LASTUPDATE=${X[3]}
X=${ lsuser -a maxage "$1" ; }
S=${X#*=}
(( S *= 604800 ))
(( S += LASTUPDATE ))
printf "$S\n%T\n" "#$S"

【讨论】:

  • 为什么 ksh 优于 perl 和 awk?
  • 如果你已经在shell中并且shell可以做到,那就让shell去做吧。
猜你喜欢
  • 2018-02-28
  • 2019-11-14
  • 2015-01-23
  • 2017-12-28
  • 2023-03-27
  • 2012-01-31
  • 2018-05-16
  • 1970-01-01
  • 2018-09-21
相关资源
最近更新 更多