Objective: Output from Linux username, passwordlastchanged, passwordexpires in human readable format.

I pulled user info from /etc/passwd and /etc/shadow for users with shell /bin/bash

join -1 1 -2 1 -t : /etc/passwd /etc/shadow |grep bin/bash|awk -F\: '{print $1";"$9";$14}'
$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

I can get a similar number as $9 and $14 for the current date

expr $(date +%S) /86400

Question: How do I output the value of $9-$(date +%s)/86400 and $14-$(date +%s)/86400 in my current one liner?

2 Answers 2


Please be aware that field 8 in /etc/shadow does NOT contain "password expiry date" but according to man shadow (on linux):

account expiration date

The date of expiration of the account, expressed as the number of days since Jan 1, 1970. Note that an account expiration differs from a password expiration. . . An empty field means that the account will never expire.

Do you want "password expiration" or "account expiration"?

With the join in your question, all "shadow" fields will be shifted by 6 for further evaluation. The grep command is unnecessary; awk can do that. Try this adaption of your one-liner:

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=";"
  • Ah yes: I've used the account expiration date on field 8 instead of maximum days valid in field 5. That changes the task slightly.
    – DavDav
    Oct 16, 2018 at 21:08
  • I'm after the number of days until password expiration or like in your example: the word 'never' if that is the case.
    – DavDav
    Oct 17, 2018 at 8:18
  • 1
    There's no "password expiration" field in shadow. You'd need to calculate it from "date of last password change" plus "maximum password age". Why don't you adapt the proposal and report back?
    – RudiC
    Oct 17, 2018 at 9:26

Use echo as follows:

 echo "$(($9-$(date +%s)/86400 ))"

$((...)) is an arithmetic expansion.

The usage of ... in $((...)) will be interpreted as an arithmetic expression. For example, a hexadecimal string will be interpreted as a number and converted to decimal. The whole expression will then be replaced by the numeric value that the expression evaluates to.

$((...)) should be quoted as to not be affected by the shell's word splitting and filename globbing.


echo "$9-$(date +%s)/86400" | bc

bc stands for basic calculator and it can handle mathematical operations.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .