xrkr
xrkr

Reputation: 209

How to fix the invalid date error in password expiry script

I was trying to write a bash script to notify expiring user passwords. I am encountering an issue when at string comparison with 'never'. How do i avoid this?

I referred to Shell script to send email before password expires and tweaked a little. However i am facing the issue at string comparison. I intend to skip the code execution if $userexp is equal to never. However it is not happening and proceeding with the execution with next part of code and i am getting below error date: invalid date ‘ never’

#!/bin/bash
#

user=user
HOST=`uname -n`
  # convert current date to seconds
  currentdate=$(date +%s)

  # find expiration date of user
  userexp=$(chage -l $user | grep 'Password expires' | cut -d: -f2)

  if [[ ! -z $userexp ]]
  then
    # convert expiration date to seconds
    #passexp=$(date -d "$userexp" "+%s")

    if [ "$userexp" = "never" ]
    then
       echo "Password for $user in $HOST is set to never expire"
   else
    # convert expiration date to seconds
    passexp=$(date -d "$userexp" "+%s")

      # find the remaining days for expiry
      (( exp = $passexp - $currentdate ))

      # convert remaining days from sec to days
      (( expday =  $exp / 86400 ))

      if (($expday < 10 ))
      then
        echo "Password  for $user in $HOST will expire in $expday day/s"
          else
          echo "Password for $user in $HOST still have much time to expire"
          fi
     fi
   fi

Why is that my string comparison not working as expected and how can i fix it.

Upvotes: 1

Views: 628

Answers (3)

L&#233;a Gris
L&#233;a Gris

Reputation: 19545

I fixed and tested your script. Issues were caused by lack of quoting sub-shell and variables

I have also secured the output of chage to the POSIX locale.

#!/usr/bin/env bash

# get user from argument 1 or default to current user
user="${1:-$(id --user --name)}"
host="$(uname --nodename)"
printf -v userhost_msg $"Password for %s in %s" "$user" "$host"
# convert current date to seconds
currentdate="$(date +%s)"

# find expiration date of user
userexp="$(
  sed -n 's/Password expires[[:space:]]*:[[:space:]]\+\(.*\)$/\1/p' < <(
    # use POSIX language to have predictable output from chage
    LC_TIME=POSIX LC_MESSAGES=POSIX chage --list "$user"
  )
)"

if [ -n "$userexp" ]; then
  if [ "$userexp" = "never" ]; then
    printf $"%s is set to never expire.\n" "$userhost_msg"
  else
    # convert expiration date to seconds
    passexp=$(date -d "$userexp" "+%s")

    # convert remaining days from sec to days
    ((expday = (passexp - currentdate) / 86400))

    if ((expday < 10)); then
      printf $"%s will expire in %d day/s.\n" "$userhost_msg" "$expday"
    else
      printf $"%s still have much time to expire.\n" "$userhost_msg"
    fi
  fi
fi

Upvotes: 1

Joao  Vitorino
Joao Vitorino

Reputation: 3256

You need to deal with th space if the answer is 'never'

userexp=$(chage -l $user | grep 'Password expires' | cut -d: -f2)

The code above will return ' never', repair the space at the beggining.

You must trim the var userexp

 if [ "${userexp##*( )} = "never" ]

add a space in the comparison

 if [ "$"userexp" = " never" ] #add a space in never

or check if string contains substring

 if [[ "$"userexp" = *"never"* ]]

Upvotes: 1

mik1904
mik1904

Reputation: 1365

if $userexp is equal to "never" your code, even if not the best you could make (no offense :) ), should work. It think it could be that there is a leading space in your case, i.e., _never where _ is a blankspace. Check it out, if that is the case, change "never" to " never" in your if condition.

Upvotes: 2

Related Questions