You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

密码过期脚本:无效日期错误与'never'字符串比较问题修复

Bash脚本密码过期通知:与'never'字符串比较失效的问题及修复

问题描述

我尝试编写Bash脚本通知用户密码即将过期,参考相关教程修改后,发现当密码设置为永不过期(即$userexp等于'never')时,字符串比较没有按预期跳过后续代码,导致出现错误: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

问题原因

问题出在userexp变量的内容上!当你用cut -d: -f2提取冒号后的内容时,chage -l的输出里Password expires:后面是带有前导空格的,比如实际输出是:

Password expires: never

所以cut提取到的内容是 never(注意前面有空格),而不是你期望的never。这就导致[ "$userexp" = "never" ]的比较永远不成立,代码会进入else分支,把带空格的 never传给date命令,自然就报错了。

修复方案

这里有几种可靠的修复方式,你可以任选其一:

方式1:去除变量前后的空格(推荐)

在提取userexp时,用xargs来自动去除字符串前后的空格和换行符:

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

xargs会自动修剪掉字符串首尾的空白字符,这样$userexp就会是纯never,比较就能正常生效了。

方式2:用正则表达式匹配

用Bash的[[ ]]结构支持正则匹配,这样不管never前后有多少空格,都能匹配到:

if [[ $userexp =~ never ]]

方式3:匹配带空格的字符串(不推荐,不够健壮)

如果你不想修改变量提取的方式,可以直接匹配带前导空格的字符串:

if [ "$userexp" = " never" ]

但这种方式不够灵活,如果输出里的空格数量变化(比如多个空格),比较就会失效,所以还是前两种方式更可靠。

修改后的完整脚本

这里是用方式1修复后的完整脚本:

#!/bin/bash
user=user  # 记得这里填上实际要检查的用户名
HOST=$(uname -n)
# convert current date to seconds
currentdate=$(date +%s)
# find expiration date of user, trim whitespace
userexp=$(chage -l $user | grep 'Password expires' | cut -d: -f2 | xargs)
if [[ ! -z $userexp ]]
then
    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 has much time to expire"
        fi
    fi
fi

另外我还修正了一处小细节:把still have改成了still has,语法更准确;同时在算术表达式里去掉了多余的$(Bash算术上下文里变量不需要加$引用)。

内容的提问来源于stack exchange,提问作者xrkr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:07:21