目标:以人类可读的格式输出 Linux 用户名、密码上次更改、密码过期。
我使用 shell 从用户中提取了用户信息/etc/passwd
并/etc/shadow
为用户提取了用户信息/bin/bash
join -1 1 -2 1 -t : /etc/passwd /etc/shadow |grep bin/bash|awk -F\: '{print $1";"$9";$14}'
where
$1 = username
$9 = number of days since last password change, calculated from 1/1_1970
$14 = number of days to password expiry date, calculated from 1/1_1970
我可以得到当前日期的类似数字 9 美元和 14 美元
expr $(date +%S) /86400
问题:如何在当前的一行中输出 $9-$(date +%s)/86400 和 $14-$(date +%s)/86400 的值?
答案1
请注意,字段 8/etc/shadow
不包含“密码到期日期”,但根据man shadow
(在 Linux 上):
帐户到期日期
帐户的到期日期,表示为自 1970 年 1 月 1 日以来的天数。请注意,帐户到期日期与密码到期日期不同。 。 。空字段意味着该帐户永远不会过期。
您想要“密码过期”还是“帐户过期”?
对于join
您的问题,所有“影子”字段都将移动 6 以进行进一步评估。该grep
命令是不必要的;awk
可以做到这一点。尝试一下你的一句台词的改编:
join -1 1 -2 1 -t : /etc/passwd /etc/shadow | awk -F: -v"TD=$(date +%s)" 'BEGIN {TD = TD / 86400} $7 ~ /bash$/ {print $1, int($9-TD), $14?int($14-TD):"never"}' OFS=";"
user1;-1429;never
user2;-1429;never
答案2
使用echo
方法如下:
echo "$(($9-$(date +%s)/86400 ))"
$((...))
是算术展开式。
...
in的用法$((...))
将被解释为算术表达式。例如,十六进制字符串将被解释为数字并转换为十进制。然后整个表达式将被表达式求值的数值替换。
$((...))
应加引号,以免受到 shell 分词和文件名通配的影响。
或者
echo "$9-$(date +%s)/86400" | bc
bc
代表基本计算器,它可以处理数学运算。