Comando executado automaticamente ao iniciar e antes de encerra sessão do usuário (sem script)

Olá senhores!

Encontrei este tópico aqui no fórum, porém, não seria viável para o cenário que imagino a utilização de scripts.

É o seguinte: preciso que ao iniciar a sessão de determinado usuário um certo comando seja executado e outro comando antes dele encerrar sua sessão quando optar por encerrá-la.

Para testar (utilizando o ZSH como SHELL), consegui colocar o comando no arquivo ~/.zshrc. Dessa forma, ao iniciar a sessão, o comando é executado. Acredito que o mesmo funcione para o BASH como SHELL no arquivo ~/.bashrc. Embora não sei se isto é recomendado.

Agora, o comando antes da sessão ser finalizada, não faço ideia de como poderia ser.

No momento não tenho exatamente o tipo de comando, mas creio que se conseguir executar determinado comando, conseguirei com qualquer outro. Para um caso de estudo, digamos que eu quisesse manualmente criar um log registrando sempre a hora que o usuário inicia sua sessão e a hora que ele finaliza.
Então, neste caso ao iniciar a sessão, o comando seria, por exemplo, um:

echo "sessão iniciada em: DATA_E_HORA" >> ~/.logsession

E quando ele fosse encerra a sessão, o comando seria praticamente o mesmo:

echo "sessão encerrada em: DATA_E_HORA" >> ~/.logsession

Se possível, gostaria de saber como fazer isso em várias opções de SHELL disponíveis.

Não que este cenário aí seja de grande utilidade. Mas espero ter deixado claro a importância “do como fazer” e o porque da minha dúvida.

Desde já, agradeço a todos! :v: :wink:

1 Curtida

O shell esta no kernel Linux e é 1 só que vem nas distro.
O que você diz é interpretador?

1 Curtida

Obrigado pela correção!
Resumindo…
Quando o usuário iniciar a seção, quero que um comando seja executado.
Quando ele encerrar a sessão, antes dela ser finalizado quero outro comando sendo executado.
Me referi a ZSH, BASH… como “SHELL” porque foi o que vi bastante internet a dentro. Mas, mesmo tendo me equivocado em descrever corretamente os termos, espero que a ideia tenha ficado clara.
Você teria alguma solução em mente @aguamole?

Chama interpretador de comando.

Eu só sei em script só que você quer sem usar script.
Você pode criar um comando dentro do arquivo de script:
bash comando

1 Curtida

Obrigado pelo vídeo… Vou analisar mas como planejo usar isso com um usuário que tenha permissões limitadas, rodar scripts não seria muito viável. Ainda assim, verei melhor esta possibilidade!

Valeu mesmo pela ajuda!

Você pode fazer um script que loga a hora de início e fica num sleep infinito. Adiciona nele o monitoramento de sinal, quando ele receber SIGTERM (fechou a sessão do terminal) daí escreve o log de saída e sai.

https://rimuhosting.com/knowledgebase/linux/misc/trapping-ctrl-c-in-bash

Veja algo semelhante no zsh.

1 Curtida

Isso poderia atrapalhar em algo o desempenho da máquina?

Depende de como você programar. Se vc deixar ele em um loop ativo, vai ficar processando. Mas se vc usar a função “sleep” o processo vai ficar “dormindo” e apenas contar como mais um processo no computador. Pro computadores atuais o uso de CPU é desprezível.

1 Curtida

Tem um problema que se o interpretador for morto com SIGKILL não vai rodar nada. O kernel detona o processo sem deixar ele fazer nada na saída.

No caso sua sugestão ou da que o @aguamole deu, se eu quisesse impedir um usuario comum de executar scripts, ainda conseguiria fazer com que as sugestões de vocês fossem executadas pelo próprio sistema independente de permissões/limitações deste usuário?

Se vc não vai deixar o usuário usar o terminal, apenas interface gráfica, pode colocar comandos ao entrar e sair da sessão.

Se vc quer apenas saber quando o usuário logou e deslogou, essa informação já fica salva no log do sistema, daí não precisaria fazer nada pra saber, além de analisar os logs…

É mais ou menos isso a intensão. Seria possível fazer isso independente de terminal?

É que isso é meio que um projeto ainda em desenvolvimento. Ainda estou vendo possibilidades para ver o que se encaixa melhor para cada situação de uso.

Você pode determinar a permissão de execução apenas pelo root ou para um grupo especifico ou use a criatividade com as permissões.
https://www.vivaolinux.com.br/artigo/Entendendo-as-permissoes-no-Linux
Você pode ate programar as permissão de execução no próprio script usando o “case” ou o “if then else elif fi”

Um exemplo de verificação se quem executa é o super usuário root:

#!/bin/bash
if [ "$(id -u)" != "0" ]; then
   echo
   echo "Voce deve executar este script como root! "
else
   echo "Voce e root!"
fi

Eu não testei esse exemplo copiei de um script do “vivaolinux.com.br”.
Deve funcionar.

1 Curtida

Sem script é até fácil, o complicado é compatibilizar com os vários shells, mas via script é gg:

#!/usr/bin/env bash

function onExit(){
  date +"Sessão encerrada em, Data: %Y %m %d - Hora: %T" >> ~/.logsession
}

# quando o script por algum motivo for fechado (EXIT), ele vai chamar a função onExit
trap "onExit" EXIT

date +"Sessão iniciada em, Data: %Y %m %d - Hora: %T" >> ~/.logsession

while true; do 
  echo "Isso é só pra encher linguiça"
  echo "basicamente serve pro script ficar rodando eternamente"
  echo "até que o usuário encerre a sessão (ou mate o processo)"
  
  echo "Já a próxima linha serve pra não abusar da CPU"
  sleep 500
done

No geral, se o usuário trocou o shell “do jeito certo”, você pode colar o código acima no começo do arquivo ‘.profile’ (exceto a primeira linha)

2 Curtidas

Uma maneira de fazer isso é pelo PAM (Pluggable Authentication Modules).

Existe um plugin chamado pam_exec (com um man pam_exec você poderá ler os detalhes sobre ele) que serve pra executar comandos em uma ou mais fases do sistema de autenticação.

tudo que você tem que fazer é ir na pasta /etc/pam.d e inserir as seguintes linhas no final do common-session

session optional pam_exec.so seteuid type=open_session comando1
session optional pam_exec.so seteuid type=close_session comando2

Sendo que o comando1 vai executar sempre que uma sessão for iniciada e o comando2 sempre que ela for terminada.

A vantagem é que o controle é centralizado (não precisa ir em cada usuário configurar) e on the fly, ou seja, basta o usuário sair da sessão. Quando entrar de novo, já vai estar valendo.

PS : Bem que está faltando um diolinux sobre o pam, né não ?

5 Curtidas

O problema é se o usuário editar o arquivo e deletar o “controle”.

Com o plugin pam_exec, ele não terá essa chance.

Muito interessante! Eu mesmo não conhecia essa funcionalidade do PAM.


Uma sugestão que eu dou para o autor do tópico é dar uma olhada nos utilitários do GNU para contas de usuários. O pacote provavelmente se chama “acct” ou algo parecido. A documentação é bem completinha.

2 Curtidas

Testando sua sugestão @chimpa_theist, fui executar os seguintes comandos:

session optional pam_exec.so seteuid type=open_session "touch ~/meuArquivo"
session optional pam_exec.so seteuid type=close_session "rm -f ~/remover"

Observação: Nomes e comandos diferentes! Quanto aos nomes, fiz isso para que não fosse algo recursivo de modo que eu não pudesse ver o resultado do teste. Mas, caso criasse, eu mudaria manualmente o nome de “meuArquivo” para “remover” antes de encerrar a sessão para testar o segundo comando. Já a diferença nos comandos, é porque tentei de diversas formas (aspas simples, duplas, sem aspas usando “~” e até digitando todo caminho) para ver se poderia ser algum erro na sintaxe do comando (embora parecesse bem improvável, quis tirar a dúvida de vez nesse ponto).

Flameshot-20210112-190449
No primeiro aparece este erro.

Já para o segundo, eu criei manualmente o arquivo “remover” na home do usuário e ele não remove.

Concordo… Me pareceu algo bem interessante e acho que seria bem interessante algo mais detalhado no estilo do @Dio!

Darie uma olhada mais detalhada assim que possível. Valeu pela sugestão!