我想让我的壁纸是季节性的(夏天、秋天、冬天、春天),而且每天更新一个季节性主题的壁纸。
所以基本上,我正在考虑有 4 个目录 ( summer, fall, winter, spring
)。在夏天,我的壁纸背景summer
每天都会在目录中的图像中旋转。然后在 9 月 21 日,墙纸目录将更改为fall
,然后墙纸将每天循环浏览这些图像,等等。
我很乐意编写脚本,但是我该从哪里开始呢?
编辑:进一步澄清是什么使这个问题独一无二。虽然创建幻灯片的方法有很多,但它们都取决于设置图像目录。我要问的是如何动态更改图像目录。所以今天的幻灯片从/images/winter/
目录中出来,春天的幻灯片从/images/spring/
目录中出来。我可以通过在每个季节更改外观设置中的目录来手动执行此操作,但是当我可以告诉计算机为我执行此操作时,我不想这样做。
基本问题是如何在春季、夏季、秋季和冬季开始时做一些事情。为此,我将创建一个在启动时运行的 bash 脚本,而不是cron
被条目堵塞。
我已经使用OP的问题“如何开发脚本?”来接近这个答案。因此,我偏离了简单发布 bash 脚本的通常方法,并通过以下方式增强了答案:
来自农民年鉴:
季节 | 天文开始 | 气象开始 |
---|---|---|
春天 | 美国东部时间 3 月 20 日星期二中午 12:15 | 3 月 1 日,星期四 |
夏天 | 美国东部时间 6 月 21 日星期四上午 6:07 | 6 月 1 日星期五 |
落下 | 美国东部时间 9 月 22 日星期六晚上 9:54 | 9 月 1 日星期六 |
冬天 | 美国东部时间 12 月 21 日星期五下午 5:23 | 12 月 1 日星期六 |
为了让我们的bash
脚本正常工作,我们需要知道每个季节从一年中的哪一天开始。
$ echo $(date --date="March 20" '+%j')
079
$ echo $(date --date="June 21" '+%j')
172
$ echo $(date --date="Sep 22" '+%j')
265
$ echo $(date --date="Dec 21" '+%j')
355
# Reference: https://unix.stackexchange.com/questions/352176/take-input-arguments-and-pass-them-to-date
Run Code Online (Sandbox Code Playgroud)
season.sh
使用以下命令打开终端:Ctrl++AltT
如果目录不存在则创建:mkdir -p ~/bin
使用以下命令编辑脚本:gedit ~/bin/season.sh
leafpad
而不是gedit
将以下行复制并粘贴到gedit
:
#!/bin/bash
# NAME: season.sh
# PATH: ~/bin
# DATE: December 15, 2018
# NOTE: Written for: https://askubuntu.com/questions/1100934/change-dynamic-wallpaper-directory-every-season/1102084#1102084
# User defined variables, change to suit your needs
# Our directory names, lines indented for cosmetic reasons only
SlideShowDir="~/Season Slide Show"
SpringDir="~/Pictures/Spring Slide Show"
SummerDir="~/Pictures/Summer Slide Show"
FallDir="~/Pictures/Fall Slide Show"
WinterDir="~/Pictures/Winter Slide Show"
CheckTripWire () {
# Our last season is in "~/Season Slide Show/CurrentSeason"
LastSeasonFilename="$SlideShowDir"/CurrentSeason
LastSeason=$(cat "$LastSeasonFilename")
[[ "$LastSeason" == "$Season" ]] && return 0 # Season still the same
# We now know our season has changed.
rm -f "$SlideShowDir"/{*,.*} # Erase all files in target
# Reference: https://askubuntu.com/questions/60228/how-to-remove-all-files-from-a-directory
echo "$Season" > "$LastSeasonFilename" # Record new season in target
# Copy new slide show based on season
if (( "$Season" == SPRING)) ; then
cp -R "$SpringDir"/. "$SlideShowDir"/
# Reference: https://stackoverflow.com/questions/3643848/copy-files-from-one-directory-into-an-existing-directory
elif (( "$Season" == SUMMER)) ; then
cp -R "$SummerDir"/. "$SlideShowDir"/
elif (( "$Season" == FALL)) ; then
cp -R "$FallDir"/. "$SlideShowDir"/
else
cp -R "$WinterDir"/. "$SlideShowDir"/
fi
} # End of CheckTripWire () function.
# Start of Mainline
DOY=$(date '+%j') # DOY = Current Day of Year
# Reference: https://stackoverflow.com/questions/10112453/how-to-get-day-of-the-year-in-shell
if ((DOY>=079 && DOY<172)) ; then
Season="SPRING" # Spring has sprung!
# Reference: https://stackoverflow.com/questions/12614011/using-case-for-a-range-of-numbers-in-bash
elif ((DOY>=172 && DOY<265)) ; then
Season="SUMMER" # Hit the beach!
elif ((DOY>=265 && DOY<355)) ; then
Season="FALL" # Rake those leaves!
else
Season="WINTER" # Shovel the snow!
fi
# Current season establish, now see if we tripped the wire
CheckTripWire
exit 0 # Command not necessary but good habit to signify no Abend.
Run Code Online (Sandbox Code Playgroud)
将文件保存在gedit
. 现在使用以下命令将其标记为可执行文件:
chmod a+x ~/bin/season.sh
Run Code Online (Sandbox Code Playgroud)
接下来我们需要将其添加到启动应用程序中。参考:如何在登录时自动启动应用程序?
注意:您可能已经在启动应用程序中进行了幻灯片放映设置。您需要在常规幻灯片放映season.sh
之前使用,因为它会删除和复制文件,如果幻灯片放映程序首先启动,这些文件将使幻灯片放映程序崩溃。
您将希望season.sh
在创建脚本时对其进行测试,而不是等待一年来查看它是否正常工作。参考:伪造特定 shell 会话的日期
最初开发脚本后,通常会在几天、几周、几个月甚至几年后对其进行增强。本节讨论您将来可能想要进行的一些增强功能session.sh
。
考虑以TAR (磁带存档)格式压缩淡季图像以节省磁盘空间。然后将cp
(复制)命令替换tar
为解压缩文件的命令。参考:23 Linux 的 tar 命令示例:
例如,我们会改变:
cp -R "$SpringDir"/. "$SlideShowDir"/
Run Code Online (Sandbox Code Playgroud)
到:
tar -xf "$SpringDir"archive.tar -C "$SlideShowDir"/
Run Code Online (Sandbox Code Playgroud)
...其他季节依此类推。
使用季节开始日的变量可以更轻松地修改脚本并使代码更易于阅读(也称为代码可读性)。
考虑为季节开始设置变量:
SpringStart=079
SummerStart=179
FallStart=265
WinterStart=355
Run Code Online (Sandbox Code Playgroud)
在脚本顶部定义变量,以便更容易发现和更改它们。您可能想在闰年执行此操作。您可能想要更改为“气象”季节开始日期,而不是“天文”开始日期。
然后更改这些行:
if ((DOY>=079 && DOY<172)) ; then
elif ((DOY>=172 && DOY<265)) ; then
elif ((DOY>=265 && DOY<355)) ; then
Run Code Online (Sandbox Code Playgroud)
对此:
if ((DOY>="$SpringStart" && DOY<"$SummerStart")) ; then
elif ((DOY>="$SummerStart" && DOY<"$FallStart")) ; then
elif ((DOY>="$FallStart" && DOY<"$WinterStart")) ; then
Run Code Online (Sandbox Code Playgroud)