Github

https://github.com/Shiliang0352/getRandomPicture

概要

有一个随机图片的接口 每次访问可以得到一张高清图片。由于是国外服务器,有诸多不稳定因素,慢,卡等(平时还挺快的),我想写一个脚本把这些随机图down到本地,这样就会稳定多了

https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture

下载东西我首先想到了 wget

wget 
-O    #指定文件名
-P    #指定目录

好的,文件名需要起一个,打算先用时间戳做文件名,达到名字不重复的目的
...
没想到shell的时间戳很繁琐!用 date 命名拿到

date
+%a    #时间格式设置,+号后跟具体格式
"+%a"   #格式设置可以是字符串样式
具体格式如下表--
%m月 (01..12)
%d日 (01..31)
%H24小时制
%d12小时制
%M分钟
%S
%e短格式天 ( 1..31)
%k24小时制 短格式
%l12小时制 短格式
%F%Y-%m-%d 2019-11-26
%s时间戳!
%N更精确的时间戳 // mac环境无效
#默认格式
date
2019年11月26日 星期二 15时01分56秒 CST

#定义格式
date +%s
1574751787

好了,先把文件名搞出来

字符串截取
${file_name:4} 从左向右第4个字符开始,截取到末尾
${file_name:4:5} 从左向右第4个字符开始,截取5个字符
#!/bin/bash
# 使用纳秒
file_name=`date +%N`
# 前面加个日期前缀,中间用纳秒再截取一部分做唯一,后面再加个后缀
file_name=`date +%F`_${file_name:4}_bg.jpg

然后使用 wget 下载,并指定成我们生成的文件名,下载的路径也要指定一下
路径是可变的,可以从脚本外接收进来比较好

使用 $n 接收脚本外传来的值
脚本中 $0 代表执行脚本时命令本身
$1 代表执行脚本时的第一个参数,$2 $3 以此类推
# 判断有没有传自定义目录进来
if [ -n "$1" ]; then
    file_path=$1
else
    file_path="./"
fi
# 把网址也弄成可自定义的
if [ -n "$2" ]; then
    file_url=$2
else
    file_url='https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture'
fi

# wget -O $file_name -P $file_path $file_url
运行到这,发现 -P指定的目录无效,都是直接下载到当前目录。
直接执行 wget -P -O 发现也不好使
经过 -P -O等参数的反复试验,发现-O是可以直接带路径的,不带路径是当前目录,且使用了 -O-P 是无效的
于是去掉 -P 变成这样
wget -O $file_path$file_name $file_url

完美 第一阶段完成,执行后可以保存在指定目录里


第二阶段

我想把图片名按数字从小到大命名,这样方便读取图片(数字+扩展名),也容易通过随机数直接做到读取随机图片的效果

1.jpg 2.jpg 3.jpg 4.jpg

文件名加上后缀,这样方便查找时区分其他不相关的文件

1-randBG.jpg 2-randBG.jpg 3-randBG.jpg

先读取选定目录下存在的文件列表,去掉后缀,拿到文件名,放到一个数组里,搞一个都是文件名的数组

其实重点就是 看看当前下载到第几张了 => 最大的那个数字是多少

字符串截取--
${var%AA*} 获取字符串从开头到 (右往左找第一个AA)之前的所有字符
${var%%AA*} 获取字符串从开头到 (右往左找最后一个AA)之前的所有字符
${var#AA*} 获取字符串从 (左往右找第一个AA)到最后的所有字符
${var##AA*} 获取字符串从 (左往右找最后一个AA)到最后的所有字符
# 找到我们的专属文件,并且倒序排列一下 `-r`
file_names=`ls -r ${file_path}*-randBG.jpg 2>/dev/null`
# 判断 ls 是否出错
if [ $? -eq 1 ]
    # 找不到序号为 1
    then file_num=1

elif [ -z $file_names ]

    # 如果为空 序号为 1
    then file_num=1

else
    # 处理数组
    a=0
    for str in $file_names
        do
            file_names_array[a]=${str##*/}
            let a++
        done

    # 使用sort排序 获得文件名数组
    file_names=($(echo ${file_names_array[*]} | tr ' ' '\n' | sort -n -r))
    # 拿到最大数值
    max_file_name_num=${file_names[0]%%-*}
    let max_file_name_num++
fi
# 新文件名
file_name=${max_file_name_num}-randBG.jpg

# 下载
wget -O $file_path$file_name $file_url
# -n 参数可以让 echo 命令不增加换行符
echo -n $max_file_name_num > ${file_path}/max
exit;
效果

用PHP读一个随机图

$max_num=file_get_contents('./images/max');
echo mt_rand(1,$max_num).'-randBG.jpg';

优化

  • 下载 wget 结果加判断,不然下载失败max文件数字依然增加
  • 增加一个下载文件类型判断,这样可以下载不同的东西了

完整脚本

#!/bin/bash

# 参数判断一下 没传值默认当前目录
if [ -n "$1" ]; then
    file_path=$1
else
    # 不方便传值的请在这里填写路径,例如宝塔
    file_path="./"
fi
# 同样的 下载的网址参数
if [ -n "$2" ]; then
    file_url=$2
else
    file_url='https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture'
fi

# 第二阶段 开始搞文件名 找当前目录内存在的最大数字

# 找到我们的专属文件,并且倒序排列一下 `-r`
file_names=`ls -r ${file_path}*-randBG.jpg 2>/dev/null`
# 判断 ls 是否出错
if [ $? -eq 1 ]
    # 找不到序号为 1
    then file_num=1

elif [ -z $file_names ]

    # 如果为空 序号为 1
    then file_num=1

else
    # 处理数组
    a=0
    for str in $file_names
        do
            file_names_array[a]=${str##*/}
            let a++
        done

    # 使用sort排序 获得文件名数组
    file_names=($(echo ${file_names_array[*]} | tr ' ' '\n' | sort -n -r))
    # 拿到最大数值
    max_file_name_num=${file_names[0]%%-*}
    file_num=$[$max_file_name_num+1]
fi

file_name=${file_num}-randBG.jpg

# 下载
wget -O $file_path$file_name $file_url
echo -n $file_num > ${file_path}/max
exit;