ksh 纪元到日期时间格式
ksh epoch to datetime format
我有一个脚本可以找到任何用户密码的到期日期。脚本可以找到以秒(纪元)为单位的过期日期,但无法将其转换为日期时间格式。
#!/usr/bin/ksh
if (( ${#} < 1 )) ; then
print "No Arguments"
exit
fi
lastupdate=`pwdadm -q |awk '{print ;}'`
((lastupdate=$lastupdate+0))
maxagestr=`lsuser -a maxage `
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 值为真。如果我输入 expdateseconds 的值作为 localtime() 函数的参数,该函数将以日期时间格式显示日期。
但是,如果我键入 $expdateseconds 变量,该函数将无法正常工作,并且 return 01.01.1970 始终如此。
如何输入变量作为 localtime() 函数的参数?
Shell 变量不在单引号内展开。因此,在您的代码中,perl 不是 "seeing" shell 变量,而是看到一个未初始化的 perl 变量,其值默认为零。 Shell 变量 是 在双引号内扩展的,所以在这种情况下,这就是您需要做的:
expdate=`perl -le "print scalar(localtime($expdateseconds))"`
正如@JeffY 所说,您的问题是引号。你也可以不使用 perl(假设你的 date
命令是 GNU 版本):
expdate=`date -d @$expdateseconds`
尽管如此,因为您使用的是 ksh - 实际上,任何现代 POSIX shell - 我建议您避免使用 `...`,这可能会导致引号的混淆行为,并且使用 $(
...)
代替。
expdate=$(date -d @$expdateseconds)
这不是代码审查,但我有一些关于您的脚本的其他提示。通常的规则是将错误消息(如 "No arguments")发送到标准错误而不是标准输出(使用 print -u2
),并在出现使用错误时以非零值(通常为 1)退出。
每当将参数传递给命令时,例如 pwadm -q
,你 运行 除非你双引号参数 pwadm -q ""
.
您的算术中混合了 let
、((
和 expr
。我建议您使用 typeset -i
varname 声明所有数字变量,并只使用 ((
...))
进行所有算术运算。在 ((
...))
中,您不必担心通配符会把事情搞砸(如果当前目录中有一个名为 let a=b*c
的文件,let a=b*c
将扩展为语法错误=27=],例如;(( a=b*c ))
不会)。您也不需要在变量上加上美元符号(这只会使 shell 将它们转换为字符串,然后再次解析它们的数值),或者向它们添加 0 只是为了确保它们是数字。
没有必要既不使用awk也不使用perl。例如:
#!/usr/bin/ksh93
[[ -z ]] && print -u2 "No Arguments" && exit 1
typeset -i LASTUPDATE S
X=( ${ pwdadm -q "" ; } )
LASTUPDATE=${X[3]}
X=${ lsuser -a maxage "" ; }
S=${X#*=}
(( S *= 604800 ))
(( S += LASTUPDATE ))
printf "$S\n%T\n" "#$S"
我有一个脚本可以找到任何用户密码的到期日期。脚本可以找到以秒(纪元)为单位的过期日期,但无法将其转换为日期时间格式。
#!/usr/bin/ksh
if (( ${#} < 1 )) ; then
print "No Arguments"
exit
fi
lastupdate=`pwdadm -q |awk '{print ;}'`
((lastupdate=$lastupdate+0))
maxagestr=`lsuser -a maxage `
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 值为真。如果我输入 expdateseconds 的值作为 localtime() 函数的参数,该函数将以日期时间格式显示日期。
但是,如果我键入 $expdateseconds 变量,该函数将无法正常工作,并且 return 01.01.1970 始终如此。
如何输入变量作为 localtime() 函数的参数?
Shell 变量不在单引号内展开。因此,在您的代码中,perl 不是 "seeing" shell 变量,而是看到一个未初始化的 perl 变量,其值默认为零。 Shell 变量 是 在双引号内扩展的,所以在这种情况下,这就是您需要做的:
expdate=`perl -le "print scalar(localtime($expdateseconds))"`
正如@JeffY 所说,您的问题是引号。你也可以不使用 perl(假设你的 date
命令是 GNU 版本):
expdate=`date -d @$expdateseconds`
尽管如此,因为您使用的是 ksh - 实际上,任何现代 POSIX shell - 我建议您避免使用 `...`,这可能会导致引号的混淆行为,并且使用 $(
...)
代替。
expdate=$(date -d @$expdateseconds)
这不是代码审查,但我有一些关于您的脚本的其他提示。通常的规则是将错误消息(如 "No arguments")发送到标准错误而不是标准输出(使用 print -u2
),并在出现使用错误时以非零值(通常为 1)退出。
每当将参数传递给命令时,例如 pwadm -q
,你 运行 除非你双引号参数 pwadm -q ""
.
您的算术中混合了 let
、((
和 expr
。我建议您使用 typeset -i
varname 声明所有数字变量,并只使用 ((
...))
进行所有算术运算。在 ((
...))
中,您不必担心通配符会把事情搞砸(如果当前目录中有一个名为 let a=b*c
的文件,let a=b*c
将扩展为语法错误=27=],例如;(( a=b*c ))
不会)。您也不需要在变量上加上美元符号(这只会使 shell 将它们转换为字符串,然后再次解析它们的数值),或者向它们添加 0 只是为了确保它们是数字。
没有必要既不使用awk也不使用perl。例如:
#!/usr/bin/ksh93
[[ -z ]] && print -u2 "No Arguments" && exit 1
typeset -i LASTUPDATE S
X=( ${ pwdadm -q "" ; } )
LASTUPDATE=${X[3]}
X=${ lsuser -a maxage "" ; }
S=${X#*=}
(( S *= 604800 ))
(( S += LASTUPDATE ))
printf "$S\n%T\n" "#$S"