上回说到自己写了个脚本去下载国家地理的每日一图,今天就完善(其实就是再总结成中文版滴)一下,增加一个必应的壁纸,在 Mac 上自动下载壁纸到指定文件夹,简单设置一下让 Mac 自动切换壁纸,给既定的生活添点变化。
国家地理和必应壁纸下载脚本
首先,选择一个文件夹,比如说 /Users/franklin/Pictures/Wallpapers/
,下面就指 Wallpapers
文件夹啦。在里面新建两个脚本。
首先是国家地理的下载脚本,就叫 ng.sh
吧:
#!/bin/bash
# change directory to where the script resides
BASEDIR=$(dirname $0)
cd "$BASEDIR"
# get html
data=$(curl -s https://www.nationalgeographic.com/photography/photo-of-the-day/)
if [ -n "$data" ]
then
# get img url
imgurl=$(grep 'property="og:image"' <<< "$data")
imgurl="$(cut -d"\"" -f4 <<< $imgurl)"
# get image name from canonical link & get publish date
name=$(grep 'rel="canonical"' <<< "$data")
name="$(cut -d"\"" -f4 <<< $name)"
name="$(cut -d"/" -f8 <<< $name)"
date=$(grep 'meta property="gsa_publish_date"' <<< "$data")
date="$(cut -d"\"" -f4 <<< $date)"
date=$(echo "$date" | sed 's/-//g')
file="$date - $name.jpg" # format file name
if [ -f "$file" ]
then
filesize=$(wc -c < "$file")
filesize=$(($filesize)) # parseInt
actualsize="$(curl -s -L -I $imgurl | awk 'tolower ($1) ~ /^content-length/ { print $2 }')"
actualsize=$(echo $actualsize | sed "s/$(printf '\r')\$//") # remove carriage return on macOS
# check file integrity
# sometimes the image may partially downloaded because of network interrupt
if [ "$filesize" -eq "$actualsize" ]
then
echo "$(date) - '$file' already downloaded"
else
curl -s "$imgurl" > "$file"
echo "$(date) - image saved as $file"
fi
else
curl -s "$imgurl" > "$file"
echo "$(date) - image saved as $file"
fi
else
echo "$(date) - connection failed"
fi
说实话,国家地理的图良莠不齐,自然风光的我很喜欢,人文的很多时候我不太能接受作为壁纸使用。
接下来是颇受好评的必应壁纸,就叫 bing.sh
吧,和国家地理的脚本类似:
#!/bin/bash
# change directory to where the script resides.
BASEDIR=$(dirname $0)
cd "$BASEDIR"
bing="https://www.bing.com"
# the idx parameter determines where to start from. 0 is the current day,
xmlURL="https://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=zh-CN"
# Valid options: "_1024x768" "_1280x720" "_1366x768" "_1920x1200" "_1920x1080" "_UHD"
picRes="_UHD"
# The file extension for the Bing pic
picExt=".jpg"
# the XML data retrieved from xmlURL, form the fully qualified
# URL for the pic of the day, and store it in $picURL
data=$(curl -s $xmlURL)
if [ -n "$data" ]
then
picURL=$(cut -d '>' -f13 <<< "$data")
picURL=$(cut -d '<' -f 1 <<< "$picURL")
picURL=$bing$picURL$picRes$picExt
date=$(cut -d '>' -f5 <<< "$data")
date=$(cut -d '<' -f1 <<< "$date")
name=$(cut -d '>' -f15 <<< "$data")
name=$(cut -d '<' -f 1 <<< "$name")
name=$(cut -d '(' -f 1 <<< "$name")
len=${#name}
file="$date - ${name:0:len-1}$picExt"
if [ -f "$file" ]
then
filesize=$(wc -c < "$file")
filesize=$(($filesize)) # parseInt
actualsize="$(curl -s -L -I $picURL | awk 'tolower ($1) ~ /^content-length/ { print $2 }')"
actualsize=$(echo $actualsize | sed "s/$(printf '\r')\$//") # remove carriage return on macOS
if [ "$filesize" -eq "$actualsize" ]
then
echo "$(date) - '$file' already downloaded"
else
curl -s "$picURL" > "$file"
echo "$(date) - image saved as $file"
fi
else
curl -s "$picURL" > "$file"
echo "$(date) - image saved as $file"
fi
else
echo "$(date) - connection failed"
fi
根据 @heroncrow 的建议增加的 _UHD
,可以获取必应高清壁纸了,👍
根据 @ystävä 的提议,修复了 awk
忽略大小匹配的问题,多谢。
这两个脚本分别负责下载国家地理和必应每天的壁纸,下载的壁纸文件存放在这个脚本所处的文件夹里面,也就是 Wallpapers
文件夹里。文件是按“日期 - 图片名”形式存储的,也方便管理。
这两个脚本是硬编的,大佬们见笑啦 😊。
再新建另一个脚本,就叫 wallpapers.sh
吧,用来调用上面这两个脚本:
#!/bin/bash
path=$0
BASEDIR=$(dirname "$path")
cd "$BASEDIR"
./bing.sh
./ng.sh
exit
今后如果要添加其他的壁纸源,照猫画虎添进来就好。
然后,需要给这三个脚本赋予可执行的权限:
chmod u+x /Users/franklin/Pictures/Wallpapers/ng.sh
chmod u+x /Users/franklin/Pictures/Wallpapers/bing.sh
chmod u+x /Users/franklin/Pictures/Wallpapers/wallpapers.sh
launchctl 定时运行壁纸下载脚本
在 ~/Library/LaunchAgents/
里新建一个 plist 文件,例如 com.frankindev.wallpapers.plist
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- give a unique Label -->
<key>Label</key>
<string>com.frankindev.wallpapers.plist</string>
<!-- path to the script -->
<key>ProgramArguments</key>
<array>
<string>/Users/franklin/Pictures/Wallpapers/wallpapers.sh</string>
</array>
<!-- set the interval time in seconds -->
<key>KeepAlive</key>
<true/>
<key>ThrottleInterval</key>
<integer>7200</integer>
<!-- std output -->
<key>StandardOutPath</key>
<string>/Users/franklin/Pictures/Wallpapers/wallpapers.log</string>
<!-- std err output -->
<key>StandardErrorPath</key>
<string>/Users/franklin/Pictures/Wallpapers/wallpapers.err</string>
</dict>
</plist>
按实际情况更改里面的 Label
、文件路径和运行间隔这些。
这里设定的是每两个小时运行一次下载脚本。在上面的具体脚本里面其实设置了检查文件是否已经下载,这么做也就是图个安心,以防网络不稳定当天的壁纸没下载到(或不完整)。
更新:
查看 log 的时候发现进程似乎是在不断运行。根据 Mac launchctl StartInterval not working 的提示,请更改以下片段(上面的代码已经改过了,有类似情况的同学可注意下):
<key>StartInterval</key>
<integer>7200</integer>
改为:
<key>ThrottleInterval</key>
<integer>7200</integer>
这样脚本程序每两小时最多运行一次。
建好 plist 文件后,需要使用 macOS 的 launchctl
添加到系统的启动进程里:
launchctl load -w ~/Library/LaunchAgents/com.frankindev.wallpapers.plist
Okay,这样系统就会悄悄滴每两个小时去运行一次壁纸下载脚本了。如果想了解更多关于 launchctl
的资料,这边请。
需要注意,如需修改 plist 文件中的内容,需要先 unload
再 load
才会生效:
launchctl unload -w ~/Library/LaunchAgents/com.frankindev.wallpapers.plist
launchctl load -w ~/Library/LaunchAgents/com.frankindev.wallpapers.plist
使用 Linux 的同学当然也可以用 crontab 来替换 launchctl。
Mac 自定义壁纸设置
壁纸到手了,就只需在 Mac 系统设置里添加壁纸文件夹,以及简单的个性化设置一下。如下图左下角那个 +
添加自定义文件夹:
如有不满意的壁纸今后去文件夹里删除掉就好了,其他地方下载的壁纸也可以丢到这个文件夹里统一管理。
我其实是将这个 Wallpapers
文件夹放在 OneDrive 里面进行同步的,当使用同一个账户切换到 Windows 下时我照样可以使用这些壁纸设置桌面。
macOS shortcuts
再来一个,在 mac 上创建了一个 shortcuts,可以直接叫 Siri 帮我更新当天的必应壁纸了。
👆上面的分享链接不知道能不能打开,也可以照下图自己创建一个:
基本上就是获取链接,下载图片文件,存储到指定的 ~/Pictures/wallpaper.jpg
里,每次执行都会覆盖这个文件,然后设定新壁纸。
如果不指定文件路径,直接运行 Set wallpaper to
-> Contents of URL
, 它也会下载文件到 Pictures
下,但是每次下载都会在文件名后添加 -1
、-2
后缀,浪费空间了~
以上,有什么建议、意见留言讨论哈!