新闻资讯

新闻资讯 媒体报道

Shell脚本实现自动从网络更换桌面背景(一)

编辑:011     时间:2022-01-12

虽然很多人说在linux上面工作不需要考虑桌面和美观,我呢,也不完全赞同这个观点,毕竟我这种咸鱼也没钱买再买一台别的电脑了。既然如此那总是对着沉闷死板一成不变的桌面咸鱼也会觉得无聊吧。更何况咱还有一颗折腾的心,怎么能放过好好把玩它的机会呢?

喏!正如你们看到的,这是最终效果(你也许会纳闷这个天气和日期是不是图片本身? : ) )。看到这个图片就代表我的程序已经写出来了,所以诸位不用担心我会弃坑(至少这个项目不用担心)。不过一次成型这个shell脚本,内容太多,所以拆开写。具体拆几章?先写了看吧。到时候写成几章是几章。值得一提的是我使用换壁纸的工具是lxde桌面自带的pcmanfm,所以为了实现的完整性,请诸位也遵循我在专栏里面第一篇文章中记录的安装流程安装lxde桌面环境。(当然,如果你用惯了别的DE,本篇文章大部分内容也是适用的,只需要在更换背景图的那一步骤改成你的桌面DE支持的换壁纸工具命令就好,经SeanHou提醒,ubuntu用户除了需要修改换壁纸的命令之外,ub默认sh解析器是dash而非bash,需要另外修改#!/bin/bash,或者一劳永逸的把sh重链接到bash上!)

在急于写代码之前,不妨梳理一下逻辑流程。

  1. 访问url
  2. 解析内容,解析出url可能涉及到递归1,2两个步骤
  3. 爬取图片
  4. 设置背景图

天气和日期的获取以及怎么在图片上显示留着之后的篇幅写。那么首先,让我们实现从网络下载图片并设置背景图吧。访问url获取http报文的工具程序是curl。我们可以先在终端里面尝试

$>curl www.baidu.com

得到了报文之后面临的第一个棘手的问题就是解析报文。这个问题可以看作从字符串中提取某种模式的子字符串。有一个常用的工具程序就是为此而生的那就是“grep”,这同时也需要诸位对正则表达式有一定了解了。比如我们从“abcdefxx.yy.com/ok.jpg zzz”字符串中提取http开头jpg结尾的子字符串。

$>echo abcdefhttp://xx.yy.com/ok.jpgzzz|grep -P "http.*?jpg" -o

grep的参数-P是使用模式匹配,也就是常见正则匹配,alpha匹配,-o是输出匹配文本(不见这个参数仅仅只会把匹配的文本变色标记)

好的,熟悉了这两个工具的使用之后,我们可以来把它们串起来调用一下。在这里呢,我要隆重的介绍一个图片网站——优美图 - 收录优美图片 TOPIT.ME,为什么是这个网站呢,因为它的确很惊艳到我,我非常很喜欢这个网站,里面的图片质量非常高,很养眼。而且它的url设计融入了restful哲学,这很方便用curl来调用,可以免去一大堆参数。方便我们爬取。比如这个url

http://www.topit.me/tag/PC壁纸/hot

就把壁纸标签下热门给选择出来了。

开打浏览器F12检查报文

可以发现每个豆腐块的元素都是一个class="e m"的div。而这个div里面的img元素上面的src就是我们寻找的图片地址了。当然我们需要的是大图而不是这个小图。所以点进去再找找线索吧。

找到下载原图的链接发现大图的下载地址,我们不妨比较两段字符串。我们在首页捕获的图片名字和大图的图片名字比较差异发现,小图是以“m.jpg”结尾而大图以“o.jpg”结尾。难道是巧合吗?为了验证一下猜想,取首页上另一个小图,直接修改把结尾处的m换成o。会发现真的如此。这么一来,原本预计的工作量就大大缩减了,至少我们不用解析一次首页,然后再次curl再解析。

那么我们获取到报文再把http开头m.jpg结尾的字符串给找出来的程序该怎么写就很清晰了。

$>curl http://www.topit.me/tag/PC壁纸/hot|grep -P "http:[^>]*?m.jpg" -o

[^>]意思是取不是“>”的字符。^是取反的意思。如果不这么做而使用“.”通配,会直接匹配到第一个http开头到最后一个m.jpg,这不是我们需要的。另外细心的人应该发现了curl打印了我们不需要的%Total Spent Left等统计信息,关闭统计信息只需要加参数-s(silent)就可以了。grep的参数可以合并写也就是-oP。还有就是我们只需要一张图片,所以我们可以取随机一张图片。而且这个curl第一页固定20张图片。还记得上一篇博客介绍过的$RANDOM随机变量吗?我们只需要膜除20就得到20以内随机数了。那么取指定行呢?接着请出sed工具。sed工具可以批量修改,提取文本文件。用sed工具提取指定行就是sed -n 2p filename(如果使用管道filename省略)就是提取第2行。更多的用法大家参考男人man sed或者直接sed -h获取帮助。

所以随机取一条就变成了

curl -s http://www.topit.me/tag/PC壁纸/hot | \
grep -oP "http:[^>]*?m.jpg" |sed -n $[$RANDOM%20+1]p

膜除20后加1,防止为0。

OK,再然后,就是把m.jpg修改成o.jpg,修改字符串,sed的修改字符串的方式为

sed 's/原字符串/新字符串/' filename  #当使用管道标准输入的时候 filename省略

于是完整的语句如下

curl -s http://www.topit.me/tag/PC壁纸/hot | \
grep -oP "http:[^>]*?m.jpg" | \
sed -n $[$RANDOM%20+1]p|sed 's/m.jpg/o.jpg/'

如此我们就拿到了图片地址,那么接下来就是下载了,下载会使用wget工具。纯净如archlinux是没有预装这个工具的,使用命令

sudo pacman -S wget

wget用来下载文件的方式是

wget "http://xxxx.xxx.xx/xxx.jpg" -O myfilename.jpg

那个重命名参数是大写的O不是数字0。

好了,下面正式开始写就脚本,首先还是进入~/workspace目录使用mkdir wallpaper目录。防止代码污染。新建编辑文件changewallpaper.sh

#!/bin/bash function debug { #debug函数用来调试,可以直接往标准输出打印也可以echo $@ > xx.log #来打日志发布正式版的时候还可以直接把此函数注释掉,避免打印调试信息 echo $@ } function downpaper { local img=`curl -s http://www.topit.me/tag/PC壁纸/hot \  |grep -oP "http:[^>]*?m.jpg" \  |sed -n $[$RANDOM%20+1]p \  |sed 's/m.jpg/o.jpg/'` debug start downloading [$img] wget $img -O paper.jpg #pcmanfm是lxde的默认配置工具,-w用来设置壁纸,pwd是取当前路径 #这是由于pcmanfm要求绝对路径,这里最好不要使用pwd而是写成您的项目路径 #因为未来这个脚本会添加进crontab job中去,而那个job的执行目录是根目录 #而非您现在的workspace目录 pcmanfm -w `pwd`/paper.jpg } downpaper

让我们看看效果吧

$>chmod +x changewallpaper.sh
$>./changewallpaper.sh

壁纸已经成功更换了。。。

本期代码已更新github

nikoloss/linuxstuff

很强势。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

回复列表

相关推荐