Script não executa via cron
Boa tarde,
Estou a mais de três semanas tentando resolver dois problemas no qual não acho a solução, gostaria da ajuda de todos se possível.
PRIMEIRO PROBLEMA
Existe uma forma de adaptar este script para ele não perder os agendamentos anteriores?
if [ "`crontab -l | grep 'change_wallpapers.sh'`" ]; then
echo "Agendamento ja foi criado..."
else
CHECKLIST=$(ls /home|cut -d: -f2);
LISTUSER=/tmp/list_users.txt
echo $CHECKLIST|sed 's/ /\n/g' > $LISTUSER
while read USER
do
cat <<- EOF > cron.jobs
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""
DISPLAY=:0
HOME=/home/${USER}
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
# Agendamento para troca de papel de parade.
*/15 * * * * /home/${USER}/.scripts/bin/change_wallpapers.sh
EOF
cat cron.jobs|crontab -u $USER -
echo -e "Agendamento do usuario \033[1;33m${USER}\033[0m criado com sucesso..............................(\033[0;32m OK \033[0m)"
echo -e ""
done < $LISTUSER
fi
SEGUNDO PROBLEMA
O script não quer funcionar no agendamentos de todos usuários comum, mais ele funciona caso seja executando via terminal logado na sua área de trabalho. já com super usuário o agendamento funciona, andei pesquisando no google sobre o problema, achei varias dicas como export DISPLAY=:0 e muitos outro, mais nao obtive sucesso, li que tinha haver com DBUS, mais tb não consegui nada, por favor alguém pode ajudar?, preciso implementar esta solução em um parque de 750 maquina com Linux Mint Cinnamon 18.2.
#!/bin/bash
# Obitendo o usuario real
RUID=$(who | awk 'FNR == 1 {print $1}')
# Traduzir o nome de usuário real para o ID do usuário real
RUSER_UID=$(id -u ${RUID})
# Definir o papel de parede de uma lista
LIST="001.jpg 002.jpg 003.jpg 004.jpg 005.jpg 006.jpg 007.jpg 008.jpg 009.jpg 010.jpg 011.jpg 012.jpg 013.jpg 014.jpg"
# Local de armazenamento dos papeis de parede
BASE="file:///home/${USER}/.wallpapers/"
# O papel de parede atual
current=`gsettings get org.cinnamon.desktop.background picture-uri`
opacity=`gsettings get org.cinnamon.desktop.background picture-opacity`
options=`gsettings get org.cinnamon.desktop.background picture-options`
# Percorrer a lista até encontrarmos o fim
matched=0
new=""
for wp in $LIST
do
if [ $matched -eq 1 ]
then
new="${BASE}${wp}"
break
elif [ "'${BASE}${wp}'" = "${current}" ]
then
matched=1
fi
done
# if "$new" is blank, then we show the first shot
if [ "$new" = "" ]
then
new=${BASE}${LIST%% *}
fi
# Definir o papel de parede
gsettings set org.cinnamon.desktop.background picture-uri \'${new}\'
gsettings set org.cinnamon.desktop.background picture-opacity ${opacity}
gsettings set org.cinnamon.desktop.background picture-options ${options}
SCRIPT COMPLETO
#####################################################################
#!/bin/bash
# Autor: Erik P. Ghijs <[email protected]>
# Script simples que criar agendamento para todos usuários no sistema.
# PATH local
PATH=/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin
export PATH
#
if [ "`crontab -l | grep 'change_wallpapers.sh'`" ]; then
echo "Agendamento ja foi criado..."
else
CHECKLIST=$(ls /home|cut -d: -f2);
LISTUSER=/tmp/list_users.txt
echo $CHECKLIST|sed 's/ /\n/g' > $LISTUSER
while read USER
do
cat <<- EOF > cron.jobs
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""
DISPLAY=:0
HOME=/home/${USER}
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
# Agendamento para troca de papel de parade.
*/15 * * * * /home/${USER}/.scripts/bin/change_wallpapers.sh
EOF
cat cron.jobs|crontab -u $USER -
echo -e "Agendamento do usuario \033[1;33m${USER}\033[0m criado com sucesso..............................(\033[0;32m OK \033[0m)"
echo -e ""
done < $LISTUSER
fi
########################################################################
#### Criando infraestrutura para script ./change_wallpapers.sh ####
########################################################################
while read USER
do
if [ -e /home/$USER/.scripts/bin/change_wallpapers.sh ]
then {
echo -e "O script change_wallpapers.sh já existe...........................................................(\033[0;32m OK \033[0m)"
echo -e ""
}
else {
echo -e "Criando a estrutura do script \033[1;37mchange_wallpapers.sh\033[0m ...............................................(\033[0;32m STATUS \033[0m)"
echo -e ""
mkdir -p /home/$USER/.scripts/bin
echo -e 'Diretorio \033[1;37m".scripts/bin"\033[0m criado com sucesso.......................................................(\033[0;32m OK \033[0m)'
echo -e ""
chmod -R 775 /home/$USER/.scripts
echo -e 'Permissao 755 no diretorio \033[1;37m".scripts"\033[0m trocad com sucesso..........................................(\033[0;32m OK \033[0m)'
echo -e ""
chmod -R 755 /home/$USER/.scripts/bin
echo -e 'Permissao 755 no diretorio \033[1;37m".scripts/bin"\033[0m trocad com sucesso......................................(\033[0;32m OK \033[0m)'
echo -e ""
chown -c -R $USER:$USER /home/$USER/.scripts > /dev/null 2>&1
echo -e 'Certado usuario e grupo da pasta \033[1;37m".scripts"\033[0m.......................................................(\033[0;32m OK \033[0m)'
echo -e ""
cd /home/$USER/.scripts/bin
echo -e 'Dentro da pasta \033[1;37m".scripts/bin"\033[0m....................................................................(\033[0;32m OK \033[0m)'
echo -e ""
touch change_wallpapers.sh
echo -e 'Arquivo \033[1;37m"change_wallpapers.sh"\033[0m criado com sucesso.................................................(\033[0;32m OK \033[0m)'
echo -e ""
chmod +x change_wallpapers.sh
echo -e 'Permissao de execucao do arquivo \033[1;37m"change_wallpapers.sh"\033[0m trocada com sucesso.......................(\033[0;32m OK \033[0m)'
echo -e ""
chown $USER:$USER change_wallpapers.sh > /dev/null 2>&1
echo -e 'Certado usuario e grupo do arquivo \033[1;37m"change_wallpapers.sh"\033[0m trocada com sucesso.....................(\033[0;32m OK \033[0m)'
echo -e ""
cat <<"EOF" > change_wallpapers.sh
#!/bin/bash
# Obitendo o usuario real
RUID=$(who | awk 'FNR == 1 {print $1}')
# Traduzir o nome de usuário real para o ID do usuário real
RUSER_UID=$(id -u ${RUID})
# Definir o papel de parede de uma lista
LIST="001.jpg 002.jpg 003.jpg 004.jpg 005.jpg 006.jpg 007.jpg 008.jpg 009.jpg 010.jpg 011.jpg 012.jpg 013.jpg 014.jpg"
# Local de armazenamento dos papeis de parede
BASE="file:///home/${USER}/.wallpapers/"
# O papel de parede atual
current=`gsettings get org.cinnamon.desktop.background picture-uri`
opacity=`gsettings get org.cinnamon.desktop.background picture-opacity`
options=`gsettings get org.cinnamon.desktop.background picture-options`
# Percorrer a lista até encontrarmos o fim
matched=0
new=""
for wp in $LIST
do
if [ $matched -eq 1 ]
then
new="${BASE}${wp}"
break
elif [ "'${BASE}${wp}'" = "${current}" ]
then
matched=1
fi
done
# if "$new" is blank, then we show the first shot
if [ "$new" = "" ]
then
new=${BASE}${LIST%% *}
fi
# Definir o papel de parede
gsettings set org.cinnamon.desktop.background picture-uri \'${new}\'
gsettings set org.cinnamon.desktop.background picture-opacity ${opacity}
gsettings set org.cinnamon.desktop.background picture-options ${options}
############################## Fim Script ##############################
EOF
#sed -i '12i\BASE="file:///home/${USER}/.wallpapers/"' change_wallpapers.sh
}
fi
echo -e 'Codigo trasnferido para o script \033[1;37m"change_wallpapers.sh"\033[0m...........................................(\033[0;32m OK \033[0m)'
echo -e ""
done < $LISTUSER
########################################################################
#### Criando mapeamento da pasta wallpapers para usuario local. ####
########################################################################
touch /root/.smbcredentials
chmod 600 /root/.smbcredentials
cat <<"EOF" > /root/.smbcredentials
username=wallpaper
password=R@py#!1234
EOF
echo -e 'Arquivo \033[1;37m".smbcredentials"\033[0m criado com sucesso......................................................(\033[0;32m OK \033[0m)'
echo -e ""
# Backup do fstab
cp /etc/fstab /etc/fstab.original
echo -e "Copia de segurança realizada com sucesso, do arquivo fstab........................................(\033[0;32m OK \033[0m)"
echo -e ""
# Onde:
# //192.168.0.10/myfolder - /fileserver/pastacompartilhada;
# /mnt/minhapasta/ - ponto de montagem;
# cifs - tipo de sistema de arquivos;
# credentials - apontamento para arquivo com credenciais;
# iocharset - converte nomes de caminho locais para formato específico;
# sec - é o modo de segurança e determina como as senhas são criptografadas entre servidor e cliente.
# dir_mode - Se o servidor não suporta extensões CIFS Unix, sobrepõe o modo padrão para esse diretório. No caso 777, que dá permissão de leitura, escrita e gravação para todos;
# file_mode - Se o servidor não suporta a extensão CIFS, irá sobrescrever o arquivo para esse modo, no caso 777.
#
# Ex1.:
# //192.168.0.10/myfolder /mnt/minhapasta/ cifs credentials=/root/.smbcredentials,iocharset=utf8,sec=ntlm 0 0
#
# Ex2.:
# //192.168.0.250/backup /mnt/backup cifs credentials=/root/pwd.txt,user,dir_mode=0777,file_mode=0777 0 0
# Consultando /etc/fstab para criar o mapeamento via rede.
if [ "`grep -n cifs /etc/fstab`" ]; then
echo -e 'Já exister a linha no arquivo "fstab".'
else
cat << "EOF" >> /etc/fstab
#
# SMB protocol version. Allowed values are:
# 1.0 - The classic CIFS/SMBv1 protocol. This is the default.
# 2.0 - The SMBv2.002 protocol. This was initially introduced in Windows Vista Service Pack 1, and Windows Server 2008.
# 2.1 - The SMBv2.1 protocol that was introduced in Microsoft Windows 7 and Windows Server 2008R2.
# 3.0 - The SMBv3.0 protocol that was introduced in Microsoft Windows 8 and Windows Server 2012.
#
# Mapeamento local via CIFS
//10.1.8.200/wallpapers /mnt/cifs_wallpapers/ cifs credentials=/root/.smbcredentials,iocharset=utf8,vers=2.0 0 0
EOF
echo -e "Linha de mapeamento criada com sucesso............................................................(\033[0;32m OK \033[0m)"
echo -e ""
fi
# Mapeamento local para compartilhamento dos arquivos wallpapers.
mkdir /mnt/cifs_wallpapers
echo -e 'Diretorio \033[1;37m"cifs_wallpapers"\033[0m criado com sucesso....................................................(\033[0;32m OK \033[0m)'
echo -e ""
# Criando link sinbolico nos perfis local
while read USER
do
if [ -h /home/$USER/.wallpapers ];
then
echo -e "Link sinbolico já exister.........................................................................(\033[0;32m OK \033[0m)"
echo -e ""
else
ln -s /mnt/cifs_wallpapers /home/$USER/.wallpapers
echo -e "Link sinbolico criado com sucesso.................................................................(\033[0;32m OK \033[0m)"
echo -e ""
fi
done < $LISTUSER
echo -e "Link criado com sucesso...........................................................................(\033[0;32m OK \033[0m)"
echo -e ""
# Removendo lista de usuarios
rm $LISTUSER
echo -e "Lista de usuario removido com sucesso.............................................................(\033[0;32m OK \033[0m)"
echo -e ""
Re: Script não executa via cron
Re: Script não executa via cron
Mano, esse seu script ficou invocado! Mas olhando ele melhor, acho que não vai rolar com todos os usuarios. O agendamento pode ser feito de outra forma...
Seguinte, ao invés de criar o agendamento pelo root como na linha:
cat cron.jobs | crontab -u $USER -
Pode simplesmente trocá-la por:
crontab cron.jobs
Dessa forma todos os usuarios que executarem o script, poderão criar o agendamento no seu próprio /var/spool/cron/$USER, sem intervenção do root.
Re: Script não executa via cron
Tyuatsu, bom dia
Obrigado, eu desenvolvei este script para ser executado pelo root mesmo, a intensão e que ele seja executado a cada 15 min, pois casso seja criado um usuário no sistema automaticamente ele cria esta agendamento para troca de wallpapers, meus únicos problemas são no agendamento anteriores e novos, depois que este script ficar executando a cada 15min, outro e do script para trocar wallpaper não consigo executar ele via cron do usuário para trocar o papel.
Grato,
Re: Script não executa via cron
Caro colega, posso estar enganado, mas acho que esse é o caminho das pedras... no agendamento anteriores e novos vc faz assim:
remove essa linha: "cat cron.jobs|crontab -u $USER -"
adicione essa:
cat cron.jobs >> /var/spool/cron/$USER
Dessa forma irá apenas adicionar os agendamentos novos direto no cron do usuario, mantendo os antigos! Mas tem um problema, se o usuario executar crontab -r, irá apagar todos os agendamentos!
Nesse caso vc pode tentar criar um hard link nesta pasta (/var/spool/cron/$USER) para não perder o agendamento. Caso o infeliz do usuario apague sem querer o agendamento com o comando. O mais importante é ter um backup desse arquivo em outro lugar.
Se vc quiser restaurar o antigo agendamento, antes de qualquer coisa faça uma cópia do arquivo original /var/spool/$USER (se nao for usar hard link),
Por exemplo:
sudo cp -v /var/spool/$USER /home/$USER/.backup_agendamento/
Vou aplicar as alterações com o meu usuario:
./troca_wallpaper.sh
Para restaurar o arquivo original sem as novas alterações:
sudo rm -fv /var/spool/$USER
sudo cp -v /home/$USER/.backup_agendamento/$USER /var/spool/
sudo chown $USER. /var/spool/$USER
sudo chmod 600 /var/spool/$USER
Pronto agendamento antigo foi restaurado com sucesso!
Agora em relação ao segundo problema, eu alterei o seu script que muda o wallpaper, em seguida testei o mesmo aqui com o meu proprio usuario e funcionou! Mas estou usando um fedora 27 com gnome... deve rodar tbm no cinnamon de boa, só trocar o nome org.gnome para org.cinnamon.
Abaixo está o script "troca_wallpaper.sh"
#!/bin/bash
#
#
# Troca wallpaper
#
# Obtendo o usuario real
RUID=$(who | awk 'FNR == 1 {print $1}')
# Traduzir o nome de usuário real para o ID do usuário real
RUSER_UID=$(id -u ${RUID})
# Definir o papel de parede de uma lista
LIST="cat123.jpg folhassecas.jpg gotas-gotas.jpg green-lojas.jpg lagoa1.jpg lagosandinos.jpg nuvemmanha.jpg Windows_Insider_Anniversary-Ninjacat.jpg"
# Local de armazenamento dos papeis de parede
BASE="file:///home/tyuatsu/Pictures/Wallpapers/Windows 10 Anniversary/"
# O papel de parede atual
current=`gsettings get org.gnome.desktop.background picture-uri`
opacity=`gsettings get org.gnome.desktop.background picture-opacity`
options=`gsettings get org.gnome.desktop.background picture-options`
# Percorrer a lista até encontrarmos o fim
matched=0
new=""
for wp in $LIST
do
if [ $matched -eq 1 ]
then
new="${BASE}${wp}"
break
elif [ "'${BASE}${wp}'" = "${current}" ]
then
matched=1
fi
done
# if "$new" is blank, then we show the first shot
if [ "$new" = "" ]
then
new=${BASE}${LIST%% *}
fi
gsettings set org.gnome.desktop.background picture-uri "${new}"
gsettings set org.gnome.desktop.background picture-opacity ${opacity}
gsettings set org.gnome.desktop.background picture-options ${options}
gsettings get org.gnome.desktop.background picture-uri
gsettings get org.gnome.desktop.background picture-opacity
gsettings get org.gnome.desktop.background picture-options
Agora vou criar o agendamento no cron e acertar as permissoes:
su -c 'echo "* * * * * /home/tyuatsu/scripts/crontab/troca_wallpaper.sh > /dev/null 2>&1" > /var/spool/cron/${USER}'
sudo chown ${USER}. /var/spool/cron/${USER}
sudo chmod 600 /var/spool/cron/${USER}
veja como ficou o meu cron:
sudo cat /var/spool/cron/${USER}
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""
DISPLAY=:0
HOME=/home/tyuatsu
# Rodando o xeyes (agendamento antigo)
* * * * * /usr/bin/xeyes ; echo "xeyes rodou em $(date)" >> /home/tyuatsu/xeyes.log 2>&1
# Troca papel de parede (agendamento novo)
* * * * * /home/tyuatsu/scripts/crontab/troca_wallpaper.sh > /dev/null 2>&1
Sobre o agendamento acima: - A cada minuto irá rodar o programa xeyes e o script de troca de papel de parede.
Nennhum problema no status do serviço, tudo está OK!
sudo systemctl status crond
● crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2018-04-30 17:51:20 -03; 4min 29s ago
Main PID: 13314 (crond)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/crond.service
└─13314 /usr/sbin/crond -n
Apr 30 17:51:20 note01 systemd[1]: Started Command Scheduler.
Apr 30 17:51:20 note01 crond[13314]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 39% if used.)
Apr 30 17:51:20 note01 crond[13314]: (CRON) INFO (running with inotify support)
Apr 30 17:51:20 note01 crond[13314]: (CRON) INFO (@reboot jobs will be run at computer's startup.)
Apr 30 18:00:01 note01 crond[13314]: (tyuatsu) RELOAD (/var/spool/cron/tyuatsu)
fim dos meus testes, removendo os agendamentos: crontab -r