Skip to content

Instantly share code, notes, and snippets.

@bigeagle bigeagle/dnspodsh.sh forked from zrong/dnspodsh.sh
Created Feb 23, 2012

Embed
What would you like to do?
在bash中使用DNSPod的API接口实现DDNS客户端
#!/bin/bash
##############################
# dnspodsh
# 基于dnspod api构架的bash ddns客户端
# 作者:zrong(zengrong.net)
# 日期:2012-02-13
##############################
login_email=${1:?'必须提供登录名'}
login_password=${2:?'必须提供密码'}
format="json"
lang="en"
userAgent="dnspodsh/0.1(zrongzrong@gmail.com)"
commonPost="login_email=$login_email&login_password=$login_password&format=$format&lang=$lang"
apiUrl='https://dnsapi.cn/'
ipUrl='http://members.3322.org/dyndns/getip'
# 要处理的域名
domainName='yourname.net'
# 要处理的子域名
recordName='www'
# 搜索到的子域名的信息
record='初始值'
# 多长时间比较一次ip地址
delay=300
# logfile
logFile=/var/log/dnspodsh.log
getUrl()
{
curl -s -A $userAgent -d $commonPost$2 --trace trace.txt $apiUrl$1
}
getVersion()
{
getUrl "Info.Version"
}
getUserDetail()
{
getUrl "User.Detail"
}
writeLog()
{
local pre=`date`
for arg in $@;do
pre=$pre'\t'$arg
done
echo -e $pre>>$logFile
}
getDomainList()
{
getUrl "Domain.List" "&type=all&offset=0&length=10"
}
# 根据域名id获取记录列表
# $1 域名id
getRecordList()
{
getUrl "Record.List" "&domain_id=$1&offset=0&length=20"
}
# 设置记录
setRecord()
{
writeLog '设置新记录'
getUrl 'Record.Modify' "&domain_id=$domainid&record_id=$recordid&sub_domain=$recordName&record_type=$recordtype&record_line=$recordline&ttl=$recordttl&value=$newip"
sleep 10
# 再次通过dnspod的api获取最新的数据
getInitValue
}
# 通过key得到找到一个JSON对象字符串中的值
getDataByKey()
{
local s='s/{[^}]*"'$2'":["]*\('$(getRegexp $2)'\)["]*[^}]*}/\1/'
#echo '拼合成的regexp:'$s
echo $1|sed $s
}
# 根据key返回要获取的正则表达式
getRegexp()
{
case $1 in
'value') echo '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}';;
'type') echo '[A-Z]\+';;
'name') echo '[-_.A-Za-z]\+';;
'ttl'|'id') echo '[0-9]\+';;
'line') echo '[^"]\+';;
esac
}
# 通过一个JSON key名称,获取一个{}包围的JSON对象字符串
# $1 要搜索的key名称
# $2 要搜索的对应值
getJSONObjByKey()
{
grep -o '{[^}{]*"'$1'":"'$2'"[^}]*}'
}
# 获取返回代码是否正确,任何情况下,如果碰到这个代码错误,就停止程序。因为dnspod在代码错误过多的情况下会封禁账号
checkStatusCode()
{
if [ "echo $1|grep '{"status":{[^}{]*"code":"1"[^}]*}'" ];then
return 0
fi
writeLog 'DNSPOD返回错误:'$1
exit 1
}
getInitValue()
{
domainList=$(getDomainList)
checkStatusCode "$domainList"
# 从dnspod获取要设置的域名的信息
domainInfo=$(echo $domainList|getJSONObjByKey 'name' $domainName)
# 获取域名的id
domainid=$(getDataByKey "$domainInfo" 'id')
recordList=$(getRecordList $domainid)
checkStatusCode "$recordList"
# 从dnspod获取要设置的子域名记录的信息
recordInfo=$(echo $recordList|getJSONObjByKey 'name' $recordName)
recordid=$(getDataByKey "$recordInfo" 'id')
recordttl=$(getDataByKey "$recordInfo" 'ttl')
recordtype=$(getDataByKey "$recordInfo" 'type')
#recordline=$(getDataByKey "$recordInfo" 'line')
# 由于从服务器获取的线路是utf编码,目前无法知道如何转换成中文,因此在这里写死。dnspod中免费用户的默认线路的名称就是“默认”
recordline='默认'
# 从dnspod获取要设置的子域名的ip
oldip=$(getDataByKey "$recordInfo" 'value')
writeLog '初始化数据'
}
getInitValue
if [ -z $oldip ];then
writeLog '无法取得旧ip,退出程序'
exit 1
fi
while [ 1 ];do
# 由于获取到的数据多了一些多余的字符,所以提取ip地址的部分
# 从api中获取当前的外网ip
newip=$(curl -s $ipUrl|grep -o $(getRegexp 'value'))
# 如果取值错误,就继续等待下一次取值
if [ -z $newip ];then
writeLog '取值错误:'$newip
sleep $delay
continue
fi
writeLog 'newip:'$newip 'oldip:'$oldip
if [ "$newip" != "$oldip" ];then
setRecord
fi
sleep $delay
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.