话说UNIX之春秋战国

很久没有光顾UNIX这个百花园了,最近借着做UNIX培训,又徜徉了一把。
    
从87年接触UNIX,到现在已有20年了!想当初为了踏上由UNIX/C开辟出的“新大陆”而秉烛夜战的热情,恍如昨日……
    
不幸的是,由于AT&T的“慷慨”,UNIX source code走出了生她养她的Bell Laboratories,宛如亚当与夏娃走出了伊甸园,而使得地上“爬满”了芸芸众生一样,UNIX从此不再“UNI-X”!
    
潘多拉的盒子一旦打开,世界也就不再安宁。从UI、OSF,到POSIX,再到Open Group,将UNIXes拉拢到一起的尝试一波接一波,但UNIXes仍然“我行我素”,仍然标榜“我最美”!特别是各种庶出之Linux,更是让UNIX这一本已“人满为患”的大家族更加“人声鼎沸”!
    
乱花渐欲迷人眼,现在即使想找一个UNIXes的最小公分母,也不是一件容易的事。如果说dump命令不算UNIX的classical command的话,那cron可是“与生俱来”的,但每个用户的crontab文件以及cron.allow、cron.deny已经“找不着北”了……
    
UNIX的设计理念之一是“统一”,或者说“一致”,如文件,文件是UNIX中特别伟大的概念及实现机制,就是因为其统一的处理方式。再如处理文件的命令,既可以接受作为命令行参数的文件名,也可以从标准输入读,作为过滤器使用,从而为通过管道构建强大的命令组合提供了实现机制。这种“逻辑的一致性”使得UNIX实现一些处理功能时非常优雅!
    
可惜的是,后来人却没能坚持这种优雅的“逻辑一致性”,有些命令让人非常烦恼!
    
chage是一个设置用户帐户/密码有效期的命令,可以方便地更改用户的最近(上次)修改密码的日期:
    
chage -d lastday user
    
但这里lastday要求必须是日期格式,实际上/etc/shadow中的lastday存储的是上次修改密码的日期与1970-1-1的差!而UNIX又没有提供计算两日期之差的命令,这样有时候就非常麻烦,如对于这样的任务:
    
用户peter的密码已失效,如何做才能使peter能够登录而又能够强制其立即修改密码?
    
要使peter能够登录,必须向前推算peter的lastday,而且必须将lastday转换为日期格式,才能用chage命令来设置,下面是完成此任务的Shell Script:
    
# $HOME/bin/enable.sh
######################
# for user whose password have expired,
# enable him/her to login, and force him/her to update password
#
# tested on Turbo Linux
#
# 2008-3-27
######################
#! /bin/bash
 
if [ $# -le 0 ]; then
    echo "usage: $0 user"
    exit 0
fi
 
a=($(cat /etc/shadow | grep "^$1:" | sed "s/::/:0:/g" | tr ":" " "))
maxdays=${a[4]}
inactive=${a[6]}

d=$(expr $maxdays + $inactive - 1)
c=$(expr $(date +"%s") / 86400)
c=$(expr $c - $d)
years=$(expr $c / 365)

days=0
idx=0
while [ $idx -lt $years ]
do
    y=$(expr $idx + 1970)
    days=$(expr $days + 365)
    
    r4=$(expr $y % 4)
    r100=$(expr $y % 100)
    r400=$(expr $y % 400)
    if [ $r4 -eq 0 -a $r100 -ne 0 -o $r4 -eq 0 -a $r400 -eq 0 ]; then
        days=$(expr $days + 1)
    fi
    idx=$(expr $idx + 1)
done
year=$(expr $idx + 1970)

r4=$(expr $year % 4)
r100=$(expr $year % 100)
r400=$(expr $year % 400)
ma=(31 28 31 30 31 30 31 31 30 31 30 31)
if [ $r4 -eq 0 -a $r100 -ne 0 -o $r4 -eq 0 -a $r400 -eq 0 ]; then
    ma[1]=$(expr ${ma[1]} + 1)
fi
 
day=$(expr $c - $days)
idx=0
while [ $day -gt ${ma[$idx]} ]
do
    day=$(expr $day - ${ma[$idx]})
    idx=$(expr $idx + 1)
done

month=$(expr $idx + 1)
chage -d "$year-$month-$day" $1
chage -l $1

该脚本的用法:
# enable.sh peter
 
执行过该命令之后,peter即可登录,而且必须立即更改密码。
 
该脚本之所以如此冗长,是因为要将天数转换为chage要求的日期!也许chage命令的设计/实现者认为chage主要是用来手工设置用户的lastday等参数的,参数取日期形式会更加自然,所以在内部实现了从日期到天数的转换,而将“自然”留给了用户。但对于此例所言之情况,则是“太不自然”了:要写那么冗长的代码将天数转换为日期,而后chage内部再将日期转换为天数!My God!
 
如果chage支持天数形式的-d选项,则enable.sh将会简洁、优雅得多:
 
# $HOME/bin/enable2.sh
######################
# for user whose password have expired,
# enable him/her to login, and force him/her to update password
#
# 2008-3-27
######################
#! /bin/bash
 
if [ $# -le 0 ]; then
    echo "usage: $0 user"
    exit 0
fi
 
a=($(cat /etc/shadow | grep "^$1:" | sed "s/::/:0:/g" | tr ":" " "))
maxdays=${a[4]}
inactive=${a[6]}

d=$(expr $maxdays + $inactive - 1)
chage -d $d $1
chage -l $1
 
可惜,该脚本却是不能执行的。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9537936/viewspace-218058/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/9537936/viewspace-218058/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值