Como percorrer as imagens de fundo do grub a cada inicialização

2

A resposta final já foi postada

Antes de ler a pergunta inteira, anote a resposta abaixo.

Versão curta da pergunta

No Bash, como posso encontrar o próximo item neste arquivo?

  • ... / 640x480-a.jpg
  • ... / 640x480-b.jpg
  • ... / 640x480-c.jpg

Quando o item atual é incorporado nesta string?

GRUB_BACKGROUND="/home/rick/Pictures/Wallpaper/640x480-a.jpg"

Se o item atual for a última entrada do arquivo, a primeira entrada do arquivo precisará ser selecionada. A nova entrada precisa ser atualizada no grub para a próxima inicialização.

O que foi feito até agora

Eu tenho várias imagens de fundo para o Grub. Editar manualmente /etc/default/grub para alterar a imagem de segundo plano e, em seguida, executar sudo update-grub é demorado e é provável que eu esqueça de fazê-lo. Eu gostaria que isso fosse feito automaticamente a cada inicialização / reinicialização.

Eu configurei um cron job chamado /etc/cron.d/cycle-grub-background contendo:

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

Eu confio que este trabalho será executado a cada reinicialização e não diariamente, porque às vezes o laptop não é reinicializado por muitos dias e eu não quero pular as imagens de fundo do grub disponíveis.

Ignore o código abaixo preenchido com suposições e erros perigosos

O código a seguir é fornecido apenas para referência histórica. Por favor, não use nada, pois está muito quebrado e com um design ruim.

O arquivo /usr/local/bin/cron-reboot-cycle-grub-background contém:

#!/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

Digamos que o arquivo /tmp/grub-backgrounds contenha:

640x480-a.jpg
640x480-b.jpg
640x480-c.jpg

Digamos que o arquivo /tmp/grub-background contenha:

GRUB_BACKGROUND="/home/rick/Pictures/Wallpaper/640x480-a.jpg"

A próxima foto da lista seria ...640x480-b.jpg .

Mas se a imagem atual for ...c.jpg , a próxima foto será redefinida para o início da lista e deverá ser ...a.jpg .

Preciso alinhar esse círculo como se fosse. Acho que algum tipo de file case seguido por sed está em ordem (como você pode ver pelos comentários do código), mas não consigo me concentrar nisso.

Como sempre, sou grato por todas e quaisquer ideias.

    
por WinEunuuchs2Unix 19.02.2017 / 02:59

2 respostas

2

Resposta curta

#!/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

Créditos

Depois de muito googling esta manhã, juntamente com tentativa e erro, o problema foi resolvido em 90%. Então, com incrível assistência na sala de bate-papo de Pilot6 , Terdon e Zanna foi a parte mais difícil para mim (usando sed ) foi resolvida.

Consideráveis comentários também foram publicados por cl-netbox e Byte Commander fazendo Pedir à sala de bate-papo do Ubuntu a sala de bate-papo técnico mais homogênea que eu já visitei minhas duas décadas na net.

Roteiro de chamada a cada inicialização com o cron

Crie o arquivo /etc/cron.d/cycle-grub-background contendo:

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

NOTA: crie um arquivo usando sudo powers. Não há necessidade de marcá-lo como executável, mas isso também não fará mal.

Resposta longa com declarações de depuração e variável

#!/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

Algumas notas

A resposta da versão longa usa um nome de diretório de imagem diferente da versão curta. Em ambos os casos, você precisa atualizar para qualquer diretório em que suas imagens estejam armazenadas.

sed geralmente usa / como um delimitador, mas nossos nomes de caminho / arquivo contêm / , então usamos | .

O método convencional depois de alterar /etc/default/grub é executar sudo update-grub . No entanto, isso leva 12 segundos em minha máquina. A máquina pode ser reinicializada enquanto esse processo demorado está sendo executado. Dado que systemd-inhibit teria que ser usado.

O atalho usa sed para pesquisar e substituir em /boot/grub/grub.cfg . Um backup do arquivo é feito apenas no caso de algo dar errado. A maneira como a reinicialização do cron é configurada nesta máquina, entretanto, o processo é concluído no momento em que a senha de login é digitada e uma janela de terminal é aberta para verificar a atualização.

    
por WinEunuuchs2Unix 19.02.2017 / 17:03
1

Um script simples, executado a partir de qualquer um dos scripts de inicialização do seu sistema, pode permitir percorrer as imagens de papel de parede em uma pasta específica, uma etapa por reinicialização. É muito mais rápido do que usar update-grub e uma lógica muito mais simples, além de nunca precisar executar update-grub . As desvantagens são que, se você deseja adicionar uma imagem à lista, é necessário editar o script ou escrever um pouco mais complexo para manipular o tamanho da lista de variáveis, e não é possível dizer pelos nomes dos arquivos qual imagem está em cada arquivo. .

mv wallpaper3.png wallpaperx.png
mv wallpaper2.png wallpaper3.png
mv wallpaper1.png wallpaper2.png
mv wallpaperx.png wallpaper1.png

Mesmo com uma lista de dezenas de arquivos, uma versão mais longa e real desse script deve ser executada em uma fração de segundo em um SSD ou em alguns segundos em uma unidade de disco. É simples, a lógica é óbvia e você não vai se perguntar, meses ou anos depois, o que esse script chamado pela sua startup deve fazer.

    
por Zeiss Ikon 20.02.2017 / 13:12