Уютный астраханский вечер с постпика приветствует всех, кто ещё не спит в эту пятницу.
Всё описанное ниже проводилось на операционной системе Linux Lubuntu 16.04, но это не значит, что в рамках других версий и дистрибутивов методы не являются рабочими. Здесь тег про Lubuntu, а здесь можно скачать его дистрибутив.
Решил окончательно добить тему динамической установки обоев рабочего стола в Linux с помощью скриптов и больше к ней не возвращаться. Заодно протестировал метод работы с JSON из среды bash с использованием пакета jq (официальная документация где-то здесь, тётя Вика в курсе, но, как всегда, в общих чертах, а здесь статья из Хакера). Итак, очередное приключение на 20 минут. Буквально, туда и обратно.

За основу была взята история из этого поста с PowerShell и API. Там я экспериментировал с api peapix (Free Bing Image API) и напомню, что…
The images are provided for wallpaper use only.
Для реализации функционала в Linux нужно было перевести простенький PS1 в bash, но сразу «под ключ» — чтобы и скачать, и фон установить. По ряду причин, установка pwsh мною вообще не рассматривалась.
Покопавшись в дебрях bash, я так и не смог найти ничего изкоробочного для внятной работы с json. Есть методы по парсингу и фильтрации подстрок, но это бы заняло значительное время и не выглядит, как универсальное решение. Мне же было нужно что-то аналогичное функционалу ConvertFrom-Json из вселенной PowerShell.
Именно такой удобной штуковиной и оказалась утилита jq. Ей смело можно скормить вывод curl с помощью конвейера.
Установить jq можно с помощью команды:
sudo apt install jq
После установки приступаем к экспериментам. Обрисовав логику работы будущего скрипта, мне подумалось, что было бы неплохо сначала проверить — установлена ли утилита jq в системе и что делать, если она отсутствует. Всё остальное вполне удобно помещалось в функцию getbingwalls и вызывать её стоило бы только в случае наличия jq.
При отсутствии jq — в консоль рухнет рекомендация по её установке. Хотя в дальнейшем никто не мешает запихнуть туда и команду установки, и вызов основной функции скрипта. А можно и вообще пойти путём юношеского максимализма и выполнять проверку внутри функции.
Весь скрипт выглядит так:
#!/bin/bash
# sudo chmod +x /scripts/wallpapers.sh
# Основная функция скрипта
getbingwalls()
{
# URL API
url="https://peapix.com/bing/feed"
# Папка с обоями
dir="wallpapers"
# Создать папку если её нет и перейти в неё
cd $(dirname "$0")
mkdir -p $dir
cd $(dirname "$0")/$dir
# Получаем ссылки из JSON
links=$(curl -s $url | jq -r '.[].imageUrl')
# Цикл скачивания файлов
for link in $links
do
# Получение имени файла из URL
filename=$(basename "$link")
# Скачивание файла, если его нет в папке
if [ ! -f $filename ]
then
echo "Cкачивается файл $link..."
curl -O $link --silent
fi
done
# Получаем случайный файл в папке
randomfile=$( find -type f -print0 | shuf -z -n 1 )
# Получаем полный путь случайного файла
getpath=$(readlink -f $randomfile)
# Устанавливаем случайный файл фоном рабочего стола
# Используется PCManFM
pcmanfm --set-wallpaper=$getpath
}
# Проверить установлен ли пакет JQ
if command -v jq > /dev/null
then
# Пакет установлен
getbingwalls
else
# Пакет не установлен
echo "Отсуствует пакет jq для работы с JSON!"
echo "Попробуйте его установить с помощью команды sudo apt install jq"
fi
Я постарался по максимуму снабдить код комментариями, чтобы было понятно — что делает та или иная команда. Специально не стал делать функцию чистки папки по временным критериям отбора. Подобную фичу можно встретить в коде вот этого скрипта.
Отдельно опишу только две экстравагантные вещи. Для начала — работу с json в этом блоке:
links=$(curl -s $url | jq -r '.[].imageUrl')
В переменную links помещаются ссылки из imageUrl (для понимания атрибутов, передаваемых jq, читаем json ещё раз). Далее следует цикл скачивания с проверкой наличия файла в каталоге. Получаем имя целевого файла из url с помощью команды basename. Если файл есть — не делаем ничего и двигаемся дальше по скрипту.
И в завершении — получаем путь случайного файла из папки с изображениями и передаём его файловому менеджеру для установки фоном рабочего стола. Присваивание переменной имени случайного файла было осуществлено с помощью команд find и shuf:
randomfile=$( find -type f -print0 | shuf -z -n 1 )
Если с find всё понятно, то shuf — это генератор случайных перестановок. Здесь эта команда выступает в роли ведущего «Русского лото». Ну, который бочонки из мешка вытаскивает. Только в нашём случае вместо мешка — каталог, а вместо бочонка — файл.
Скачать скрипт из терминала можно с помощью утилиты wget:
sudo wget -P /scripts https://ngdream.ru/wallpapers.sh
Обратите внимание, что скрипт скачается в папку scripts в корне файловой системы. Если папки нет — утилита её создаст.
После скачивания нужно сделать скрипт исполняемым:
sudo chmod +x /scripts/wallpapers.sh
Кстати, этот код также упомянут в качестве комментария в самом скрипте.
И, как водится, кнопка для скачивания: