最终答案已经发布
在阅读整个问题之前,请注意以下答案。
问题的简短版本
在 Bash 中,如何找到此文件中的下一个项目?
- .../640x480-a.jpg
- .../640x480-b.jpg
- .../640x480-c.jpg
当当前项目嵌入到此字符串中时?
GRUB_BACKGROUND="/home/rick/Pictures/Wallpaper/640x480-a.jpg"
如果当前项是最后一个文件条目,则需要选择第一个文件条目。需要在 grub 中更新新条目以供下次启动。
迄今已采取的措施
我有多个 Grub 背景图像。手动编辑/etc/default/grub
更改背景图像然后运行sudo update-grub
非常耗时,而且我可能会忘记这样做。我希望每次启动/重启时都自动完成。
我已经设置了一个名为的 cron 作业,其中/etc/cron.d/cycle-grub-background
包含:
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
@reboot root /usr/local/bin/cron-reboot-cycle-grub-background
我相信这项工作将在每次重启时运行,而不是每天运行,因为有时笔记本电脑很多天都没有重启,而且我不想跳过可用的 grub 背景图像。
忽略下面充满假设和危险错误的代码
以下代码仅供历史参考。请不要使用其中任何内容,因为它已严重损坏且设计不佳。
该文件/usr/local/bin/cron-reboot-cycle-grub-background
包含:
#!/bin/bash
# NAME: cron-reboot-cycle-grub-background
# DATE: February 18, 2017
# PATH: /usr/local/bin/
# DESC: Cycle through available 640x480 wallpaper for grub background
# Get list of all grub images when 1920x1080 monitor has been downgraded
# to more readable 640x480 pixel format
ls /home/rick/Pictures/Wallpaper/640x480* > /tmp/grub-backgrounds
# Find this boot grub background image name
cat /etc/default/grub | grep BACKGROUND > /tmp/grub-background
# case? to find current background in backgrounds?
# Can we run systemd inhibit lock to prevent shutdown or reboot now?
# sed? to change to next background in /etc/default/grub
# Copy /etc/default/grub to /boot/grub/grub.cfg is the same as
# running sudo update-grub with out the 12 second delay
cp /boot/grub/grub.cfg /boot/grub/grub.cfg~
cp /etc/default/grub /boot/grub/grub.cfg
# Can we release systemd inhibitor now?
# Now next reboot will have new background image
exit 0
假设该文件/tmp/grub-backgrounds
包含:
640x480-a.jpg
640x480-b.jpg
640x480-c.jpg
假设该文件/tmp/grub-background
包含:
GRUB_BACKGROUND="/home/rick/Pictures/Wallpaper/640x480-a.jpg"
那么列表中的下一张图片将是...640x480-b.jpg
。
但是如果当前图片是,...c.jpg
那么下一张图片将重置为列表的开头,并且应该是...a.jpg
。
我需要像以前一样把这个圆变成正方形。我认为某种形式的file case
后跟sed
是合理的(正如您在代码注释中看到的那样),但我不太明白。
一如往常,我感谢所有的想法。
答案1
一个简单的脚本,从系统的任何启动脚本运行,可以允许逐个浏览特定文件夹中的壁纸图像,每次重新启动一步。它比使用更快,update-grub
逻辑更简单,而且它永远不需要运行update-grub
。缺点是,如果您想将图像添加到列表中,您必须编辑脚本或编写一个稍微复杂一点的脚本来处理可变列表长度,并且您无法从文件名中判断每个文件中的图像是什么。
mv wallpaper3.png wallpaperx.png
mv wallpaper2.png wallpaper3.png
mv wallpaper1.png wallpaper2.png
mv wallpaperx.png wallpaper1.png
即使有几十个文件,这个脚本的更长的实际版本也应该在 SSD 上几分之一秒内执行,或者在磁盘驱动器上几秒内执行。它很简单,逻辑很明显,几个月或几年后,你不会想知道你的启动程序调用的这个脚本应该做什么。
答案2
简短答案
#!/bin/bash
CURR_FILE=$(cat /etc/default/grub | grep BACKGROUND) # Get grub current line
CURR_FILE=$(cut -d "=" -f 2 <<< "$CURR_FILE") # File name only
CURR_FILE=$(echo "$CURR_FILE" | tr -d '"') # Remove double quotes
for ALL_FILES in /home/rick/Pictures/Wallpaper/640x480*; do # Loop through every file
if [[ "$FIRST_FILE" == "" ]]; then
FIRST_FILE="$ALL_FILES"
elif [[ "$MATCH_FILE" != "" ]]; then
NEXT_FILE="$ALL_FILES"
break # We've got it!
fi
if [[ "$CURR_FILE" == "$ALL_FILES" ]]; then
MATCH_FILE="$ALL_FILES" # We found our current file entry
fi
done
# If $NEXT_FILE empty we hit end of list so use First file name
if [[ "$NEXT_FILE" == "" ]]; then
NEXT_FILE="$FIRST_FILE"
fi
# replace background file name in grub source file
sed -i "s|$CURR_FILE|$NEXT_FILE|g" /etc/default/grub
# replace background file name in grub configuration file
# Backup... just in case :)
cp /boot/grub/grub.cfg /boot/grub/grub.cfg~
# Short cut so we don't have to run `sudo update-grub`
sed -i "s|$CURR_FILE|$NEXT_FILE|g" /boot/grub/grub.cfg
致谢
今天早上经过大量的谷歌搜索和反复试验,问题已经解决了 90%。然后在聊天室得到了来自飞行员6,特登和扎娜对我来说最困难的部分(使用sed
)已经解决了。
也有人发表了体贴的评论cl-netbox和字节指挥官制作询问 Ubuntu聊天室是我上网二十年来所访问过的最友好、最同质的技术聊天室。
每次启动时使用 cron 调用脚本
创建包含以下内容的文件/etc/cron.d/cycle-grub-background
:
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
@reboot root /usr/local/bin/cron-reboot-cycle-grub-background
笔记:使用sudo
权限创建文件。无需将其标记为可执行文件,但这样做也不会有什么坏处。
带有调试和变量声明的长答案
#!/bin/bash
# NAME: cron-reboot-cycle-grub-background
# DATE: February 18, 2017. Modified April 9, 2017.
# PATH: /usr/local/bin/
# DESC: Cycle through available wallpaper for grub background
CURR_FILE=$(cat /etc/default/grub | grep BACKGROUND) # Get grub current line
echo "Grub line: $CURR_FILE"
CURR_FILE=$(cut -d "=" -f 2 <<< "$CURR_FILE") # File name only
CURR_FILE=$(echo "$CURR_FILE" | tr -d '"') # Remove double quotes
echo "Current file: $CURR_FILE"
FIRST_FILE=""
NEXT_FILE=""
MATCH_FILE=""
for ALL_FILES in /home/rick/Pictures/1600x900/*; do # Loop through every file
if [[ "$FIRST_FILE" == "" ]]; then
FIRST_FILE="$ALL_FILES"
fi
if [[ "$MATCH_FILE" != "" ]]; then
NEXT_FILE="$ALL_FILES"
break # We've got it!
fi
if [[ "$CURR_FILE" == "$ALL_FILES" ]]; then
MATCH_FILE="$ALL_FILES" # We found our current file entry
fi
done
# If $NEXT_FILE empty we hit end of list so use First file name
if [[ "$NEXT_FILE" == "" ]]; then
NEXT_FILE="$FIRST_FILE"
fi
echo "First file: $FIRST_FILE"
echo "Match file: $MATCH_FILE"
echo "Next file: $NEXT_FILE"
# replace background file name in grub source file
sed -i "s|$CURR_FILE|$NEXT_FILE|g" /etc/default/grub
# replace background file name in grub control file
# Backup... just in case :)
cp /boot/grub/grub.cfg /boot/grub/grub.cfg~
# Short cut so we don't have to run `sudo update-grub`
sed -i "s|$CURR_FILE|$NEXT_FILE|g" /boot/grub/grub.cfg
# Now next reboot will have new background image
exit 0
几点说明
长版本答案使用的图片目录名称与短版本不同。无论哪种情况,您都需要更新到存储图像的任何目录。
sed
通常用作/
分隔符,但是我们的路径/文件名包含它,/
所以我们使用|
它。
更改后的传统方法/etc/default/grub
是运行sudo update-grub
。但是,这在我的计算机上需要 12 秒,在运行这个漫长的过程时,机器可能会重新启动。鉴于systemd-inhibit
必须使用。
快捷方式用于sed
在 内进行搜索和替换/boot/grub/grub.cfg
。备份文件以防万一出现问题。此机器上设置 cron 重启的方式,但是,当输入登录密码并打开终端窗口检查更新时,该过程已完成。