Resolvi um problema consultando a web, infelizmente não havia nenhuma explicação sobre o porquê do comando que encontrei funcionar.
Preciso executar um script com cron/anacron e exibir o resultado em uma tela de terminal. Para fazer isso, na última linha deste script, primeiro tentei este comando:
xterm -hold -e 'cd /home/<user>/ && cat inode2 ; bash'
Só funcionou se eu mesmo executei o script. Eu o substituí por:
DISPLAY=:0 xterm -hold -e 'cd /home/mmas/ && cat inode2 ; bash'
Até onde eu posso entender, DISPLAY=:0 significa “escolha a tela de exibição atual”. E é isso que acontece: uma pequena tela de terminal aparece na janela ativa do meu laptop, exibindo o resultado do script. Nos meus arquivos ~/.bashrc e /root/.bashrc, já há um “export DISPLAY=:0.0”. Aparentemente, o cron não sabe sobre isso.
Minhas perguntas são:
- no comando modificado, DISPLAY=:0 realmente significa "exibir tela da janela ativa atual" ou algo mais?
- por que tenho que especificá-lo no início do meu comando?
Não; não pode significar isso, porque o programa não tem uma "janela ativa atual" naquele momento. Cada programa faz uma conexão independente com o display (que não é algo "herdado"), então ele não pode criar nenhuma janela até depois de ter se conectado ao display – e DISPLAY é o que diz ao programa como se conectar; é o que faz com que algum display seja "o display atual".
Então, em vez disso,
DISPLAY=:0
significa o servidor de exibição específico com o endereço de:0
. O primeiro servidor X (Xorg ou Xwayland) que inicia no sistema geralmente será:0
, o próximo será:1
, então:2
, e assim por diante.Não há garantia de 100% 1 de que sua área de trabalho estará sendo executada em display :0 – pode muito bem ser que :0 seja a tela de login e :1 seja sua área de trabalho, e assim por diante. (Ou seja, definitivamente não é algo que seu ~/.bashrc deva sobrescrever com um valor fixo.)
A sintaxe
:x.y
se refere a uma tela específica (como em exibição física) se várias exibições estiverem anexadas ao mesmo Xorg. Isso é redundante (pois:x.0
significa o mesmo que:x
qualquer outra coisa) e completamente obsoleto, pois a funcionalidade inflexível foi substituída pelo mais versátil Xrandr provavelmente nos anos 2000, se bem me lembro. Então, quando você vir,:0.0
apenas assuma:0
.O motivo é que não há uma configuração global de "exibição atual", nem em todo o sistema, nem mesmo por usuário. Uma exibição – referindo-se a um servidor X como Xorg ou Xwayland – é iniciada dinamicamente quando você faz login (e pode haver qualquer número de tais exibições, por exemplo, cinco usuários podem ter sessões gráficas ao mesmo tempo, ou o mesmo usuário pode ter duas sessões em teoria).
Não só isso, mas o X11 começou sua vida como um sistema de exibição de rede – seria possível especificar uma exibição remota como
DISPLAY=mylaptop:1
– tornando o parâmetro DISPLAY completamente específico da sessão. Por exemplo, você se conectou da estação de trabalho A ao servidor B por meio de algo como SSH ou Rlogin e executou aplicativos no servidor que exibiriam suas janelas na sua estação de trabalho (e o mesmo servidor também executaria aplicativos para dezenas de outros usuários que exibiriam em suas estações de trabalho).Então, quando você faz login em uma sessão gráfica, os processos iniciais de cada sessão são iniciados com DISPLAY já definido em seu ambiente, e é assim que eles determinam sua exibição "atual". Por exemplo, o gerenciador de login inicia uma instância do Xorg
:1
e então inicia o GNOME ou o KDE comDISPLAY=:1
o fornecido.Mas os cron jobs, como os serviços do sistema em geral, existem "fora" de qualquer sessão de usuário, então eles não têm de onde herdar DISPLAY. (Na verdade, eles podem até mesmo iniciar quando o usuário não tem display – por exemplo, na tela de login, o display pertence a uma conta do sistema – ou quando não há displays em execução.)
Uma maneira de fazer com que isso funcione de forma confiável é fazer com que seu
~/.xprofile
script (ou algum outro script executado no login) salve os valores "atuais" em um arquivo toda vez que você fizer login......e faça com que o cron job os carregue:
Embora tudo isso tenha mudado um pouco no final da década de 2010 com a adoção do systemd, que tem um recurso de "serviços de nível de usuário" (veja
systemctl --user
) – que era originalmente um recurso de "segundo plano" muito parecido com o cron, mas que… acabou executando mais e mais partes da sessão de desktop real ao longo do tempo. Isso significa que os serviços de nível de usuário agora precisam saber o valor correto de DISPLAY; seu gerenciador de login o fornece ao systemd.Então, se sua distribuição Linux suporta isso, há uma maneira mais fácil de executar tarefas cron na tela "atual", pedindo ao gerenciador de serviços para executá-las:
A situação geral não é muito diferente do Windows – todas as versões a partir do XP – onde várias sessões podem existir ao mesmo tempo; possivelmente até para o mesmo usuário. Por exemplo, se você fizer login como usuário A, mas depois alternar para o usuário B, agora você tem as sessões 0 e 1 no mesmo sistema e qualquer uma delas (ou mesmo nenhuma delas!) pode ser anexada ao display físico a qualquer momento. Muitos serviços de terceiros costumavam assumir que a sessão 0 era sempre a sessão "atual", e a Microsoft teve que erradicar tais suposições à força na transição XP→Vista.