AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / ubuntu / Perguntas / 1486581
Accepted
adrianhb
adrianhb
Asked: 2023-09-21 21:43:29 +0800 CST2023-09-21 21:43:29 +0800 CST 2023-09-21 21:43:29 +0800 CST

exibir uma caixa de diálogo antes de desligar

  • 772

Ao desligar, você verá a caixa de diálogo "Tem certeza...". Ocasionalmente, quero enviar um lembrete para mim mesmo, por exemplo, para realizar um trabalho noturno em vez de desligar. Então eu precisaria exibir outra caixa de diálogo - antes ou ao lado da caixa "tem certeza". (ou qualquer outro lembrete óbvio serviria, como mudar a cor da caixa "você tem certeza", mas isso pode envolver mexer nas entranhas dos módulos do Linux que não desejo tentar.) Não consigo obter um novo .service arquivo para funcionar conforme descrito em outro lugar. Como talvez eu não tenha acesso à tela naquele ponto do desligamento, tentei adicionar "touch /home/myuser/i_ran" ao meu script de pré-desligamento. Também tentei adicioná-lo à cláusula stop do script init.d para atd. Nem fazer nada. O que funcionaria? Idealmente, ele deveria ser executado como meu usuário atual, ou se como root meu script puder ser enviado para meu usuário atual. Estou usando notify-send para minha caixa de diálogo e executando o Ubuntu 20.04, Gnome clássico.

shutdown
  • 2 2 respostas
  • 387 Views

2 respostas

  • Voted
  1. Raffa
    2023-09-22T15:42:49+08:002023-09-22T15:42:49+08:00

    Prefácio

    Esta resposta não é uma solução direta para sua pergunta, mas sim uma importante discussão metodológica que deve orientar você e outros membros da comunidade que estão tentando ajudar na direção certa e, esperançosamente, economizar tempo e esforços.

    Discussão

    Você precisa primeiro segurar/bloquear o desligamento, o que pode ser feito de várias maneiras... Uma maneira fácil é a funcionalidade integrada fornecida pelo Free Desktopsystemd-inhibit que pode ser simplesmente usada a partir do terminal ou de um script... E então você precisa exibir um janela de diálogo com uma determinada mensagem e isso não é tão simples quanto o acima ( primeiro requisito ), pois requer um servidor de exibição em execução e uma sessão gnome gráfica do usuário em execução ... Isso, no entanto, não é possível por métodos externos ( independente) para o gnome-shell, pois no momento em que o sistema for informado sobre o "desligamento", a sessão do gnome do usuário já terá sido encerrada e eliminado quaisquer chances de possíveis interações da GUI do usuário ... Portanto, suas duas opções, até onde eu sei, são:

    • Ou, escreva seu próprio aplicativo em, por exemplo, C ou mesmo Python para implementar a inibição do GTK que aparentemente é usada por alguns aplicativos gnome como, por exemplo, gedit( O editor de texto ) no código-fonte vinculado na linha número 1407, onde a mensagem "There are unsaved documents"é aquela que será exibida em a caixa de diálogo de confirmação de desligamento do gnome e é onde sua própria mensagem estaria em seu próprio aplicativo ... No entanto, para que isso funcione, o processo do seu aplicativo precisa estar em execução no momento em que um desligamento do sistema é tentado na sessão do usuário gnome. . Aqui está um exemplo de script Python mínimo ( usando Calculator do Gnome Core Apps como um aplicativo fictício ) que fará exatamente isso e nada mais:
    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk
    
    def on_activate(app):
      win = Gtk.ApplicationWindow.new(app)
      app.inhibit(win, Gtk.ApplicationInhibitFlags.LOGOUT | 
      Gtk.ApplicationInhibitFlags.SUSPEND, 
      'It\'s time to do some tasks:\n1) Task one ...\n2) Task two ...\n3) Task three ...')
    
    app = Gtk.Application.new('org.gnome.Calculator', 0)
    app.connect('activate', on_activate)
    app.run()
    
    • Ou use a API logind D-Bus para definir e manter um bloqueio de inibidor para basicamente obter o mesmo resultado.

    Soluções alternativas

    As soluções alternativas são soluções alternativas menos nativas que podem ter a forma de, por exemplo, um script de desligamento como este:

    #!/bin/bash
    
    shut_down () {
    zenity --question --default-cancel \
    --text="You still have unfinished tasks:\n  \
    1) Task one ...\n  \
    2) Task two ...\n  \
    3) Task three ...\n\n\
    Are you sure you want to shutdown anyway?"
    }
    
    if shut_down
      then
        echo "Shutting down ..."
        # Your shutdown command(s) (either systemd or gnome-shell based) here
        fi
    

    ... e então, você precisará usar esse script em vez do botão GUI de desligamento normal ... Você pode querer desabilitar o botão padrão ou vinculá-lo a este script (Você provavelmente precisará encontrar/escrever um extensão para a parte de link ) para obter uma aparência de funcionalidade nativa.

    Outras soluções alternativas podem ser:

    • Extensões gnome-shell prontamente disponíveis para esse propósito, se você puder encontrar uma ...
    • ou você pode criar sua própria extensão gnome-shell se souber como.
    • Alguns pacotes/aplicativos para gerenciar o desligamento podem estar disponíveis através dos gerenciadores de pacotes do Ubuntu, por exemplo, APT, SNAP ou FLATPACK ... etc. ... Portanto, certifique-se de pesquisá-los.

    Discussão da sessão do Gnome

    Embora o que acontece no Gnome permaneça no Gnome, ou seja, ele tem seus próprios métodos separados do resto dos processos ( internos do Gnome, quero dizer ), mas você pode usar as ferramentas certas para observar como funciona e tentar interagir com ele ... se você executa dbus-monitorno terminal, mantém-no em execução e tenta desligar / sair, em seguida, basta clicar no botão cancelar na caixa de diálogo de desligamento, então você notará métodos sendo chamados e sinais sendo emitidos em endereços diferentes e em particular um que contém onde CanShutdownum a verificação está sendo realizada para saber se o usuário tem permissão para desligar a máquina, que você pode interceptar com algo como:

    if dbus-monitor | grep -q 'CanShutdown'
      then
        zenity --info --extra-button "Logout" --extra-button "Suspend" \
        --extra-button "Restart" --extra-button "PowerOff" --text="What to do?"
        fi
    

    ... execute-o e mantenha-o funcionando e tente, por exemplo, sair ... No entanto, isso é muito cedo.

    Outra chamada que você notará é a chamada de abertura do diálogo que deve ter algo parecido com EndSessionDialoge Open também com Canceledonde o primeiro é um método e o segundo é um sinal ... Você pode observar o diálogo, fechá-lo e enviar o sinal assim ( esteja avisado, seu sistema será desconectado/desligado, não importa o que você faça para evitá-lo ):

    if dbus-monitor | grep -q 'EndSessionDialog'
      then
        sleep 3
        gdbus call --session --dest org.gnome.Shell \
        --object-path /org/gnome/SessionManager/EndSessionDialog \
        --method org.gnome.SessionManager.EndSessionDialog.Close
        gdbus emit --session --object-path /org/gnome/SessionManager/EndSessionDialog \
        --signal org.gnome.SessionManager.EndSessionDialog.Canceled
        fi
    

    ... se você tentar isso, notará que a caixa de diálogo fecha após 3 segundos e até envia o Canceledsinal, mas sua sessão é encerrada após 60 segundos. Isso ocorre porque o Gnome define um contador em segundo plano que você precisará encontrar e encontrar uma maneira de desativá-lo também... Sim, eu sei o que você pensa :-)... De qualquer forma, você entendeu.

    • 3
  2. Best Answer
    adrianhb
    2023-09-27T21:26:40+08:002023-09-27T21:26:40+08:00

    Raffa escreveu uma longa resposta com muitos detalhes técnicos que deve ser inestimável para quem deseja criar uma solução elegante de acordo com o Gnome. Não tenho conhecimento do sistema Linux e Gnome para fazer isso, mas criei uma solução prática semelhante à da resposta de Raffa. Coloquei esta solução alternativa abaixo como a resposta aceita, mas com uma forte recomendação de ler a resposta de Raffa para obter informações técnicas, se você puder usá-la para criar uma solução melhor.

    Gambiarra

    Aplica-se a: Ubuntu 20.04/Gnome flashback metacity e muitas outras versões/mais antigas.

    Objeto

    Ser capaz de executar um script ou executável antes do início do desligamento, permitindo executá-lo ou cancelá-lo. Você pode, por exemplo, exibir um lembrete para executar um trabalho noturno.

    O problema

    O menu do sistema, acessado pelo ícone de roda dentada no canto superior direito da tela, contém a opção de menu "Desligar...". Ele não usa um arquivo .desktop, o que permitiria fácil alteração do comando a ser executado. E ignora as inibições do GTK , que os aplicativos configuram para avisar sobre alterações não salvas ou operações em andamento.

    A solução alternativa

    • Remova a opção de desligamento existente do menu do sistema.
    • Crie um novo ícone de desligamento e adicione-o à barra de menu superior.

    O novo desligamento possui um arquivo .desktop que chama um script de shell. Isto faz tudo o que você quiser, por exemplo, exibe uma caixa de informações ou executa um comando rápido. Após isso o script executa um comando de desligamento, diferente do menu do sistema, que observa as inibições do GTK e dá a opção de desligar ou cancelar.

    A solução alternativa mostrada é para desligamento, mas pode ser adaptada para operações de reinicialização, suspensão e logout.

    Para testar se uma determinada opção ou comando de desligamento ignora as inibições do GTK

    Execute o Gnome Text Editor gedit e insira algum texto em um novo arquivo sem salvar. Isso aumenta uma inibição do GTK. Certifique-se de não ter nenhuma alteração ou processo real não salvo que não deva ser interrompido e execute o encerramento. Se observar inibições do GTK, o desligamento exibirá uma caixa de diálogo "Alguns processos ainda estão em execução", listando todos os aplicativos que geraram uma inibição, com um motivo em texto, permitindo que você continue independentemente ou cancele. Caso contrário, ele será executado sem aviso prévio.

    Etapas para implementar a solução alternativa

    Remova a entrada Desligar do menu superior direito do sistema
    gsettings set com.canonical.indicator.session suppress-shutdown-menuitem true

    Substitua-o por um novo aplicativo. Este será um script de shell que fará tudo o que você quiser. Ele deve retornar quando a operação for concluída ou o usuário descartar uma caixa de informações e o script executar um comando de desligamento.

    Aqui está uma maneira básica de mostrar um lembrete se um arquivo de texto existir e contiver texto de lembrete. Salve isso como, por exemplo, ~/.local/bin/shutdown-notify.sh e execute chmod +x ~/.local/bin/shutdown-notify.shpara torná-lo executável.

    #!/bin/bash
    
    shut_down () {
    # call a shutdown command that observes application inhibit.
    # If the reminder is something you need to do in the current session,
    # you can click the Cancel button it displays.
    gnome-session-quit --power-off
    }
    
    if [ -s "$HOME/shutdown-note.txt" ]; then
      readarray -t lines < "$HOME/shutdown-note.txt"
      printf -v text '%s\n' "${lines[@]}"
      # Display an info box. Control does not return to the script until the user dismisses the box.  
      zenity --question --width=400 --ok-label="Shutdown anyway" --cancel-label="Cancel" --title="Shutdown reminder" --text="$text"
      status="$?"
      if [ "$status" = 0 ]; then
        # truncate the text file so it won't display next time
        : > "$HOME/shutdown-note.txt"
        # Do shutdown
        shut_down
      fi
    else
      shut_down   
    fi
    

    Crie um arquivo da área de trabalho para o novo desligamento

    salve o seguinte código como (por exemplo) ~/.local/share/applications/shutdown.desktop

    #!/usr/bin/env xdg-open
    [Desktop Entry]
    Name=Shutdown
    GenericName=Shutdown with reminder
    Comment=Display reminder before shutdown if set
    Exec=/home/MYUSER/.local/bin/shutdown-notify.sh
    Terminal=false
    Type=Application
    Icon=/home/MYUSER/.local/share/icons/shut-down-icon-32.png
    Categories=
    StartupNotify=false
    

    Encontre um ícone adequado ou crie um, 32x32px no formato PNG e salve no caminho fornecido acima na linha Icon= - aqui ~/.local/share/icons/shut-down-icon-32.png

    Abra a pasta que contém o arquivo da área de trabalho e arraste o arquivo até a barra de menu na parte superior da tela. O cursor mudará para uma mão e um sinal de mais e você poderá soltá-lo no lado esquerdo ou direito.

    Depois disso, a opção Desligar desaparecerá do menu do sistema, mas uma opção melhor será mostrada como um ícone na barra de menu.

    Outras melhorias possíveis

    Substituindo logout, reinicialização ou suspensão

    Para substituir o Logout (pode não ser necessário, pois obedece às inibições do GTK), execute gsettings set suppress-logout-menuitem true Para substituir o Logout, Reiniciar E desligar, execute gsettings suppress-logout-restart-shutdown true O comando para executar na parte inferior do seu script de shell seria gnome-session-quit --rebootou gnome-session-quit --logout não investiguei como substituir Suspender ou qual comando usar.

    Adicione o novo desligamento como uma opção de menu do sistema como o antigo

    Eu não tentei fazer isso. Existem extensões do Gnome que alteram as opções no menu do sistema, mas não consigo encontrar uma que faça isso ou que possa ser configurada para isso. Pode existir um, ou talvez alguém familiarizado com eles possa escrever ou adaptar um.

    use uma inibição GTK para exibir um aviso

    Se você quiser apenas exibir um aviso, o arquivo da área de trabalho poderá ser chamado gnome-session-quit --power-offdiretamente e um script de shell fornecido pelo usuário não será necessário. Isso fará com que o próprio desligamento mostre uma caixa de diálogo "Alguns processos ainda estão em execução", com um motivo em texto. Neste caso você tem que criar uma aplicação GTK fictícia , em C ou Python, que aumenta a inibição e depois roda de forma invisível em segundo plano. Em C você incluiria as linhas, por exemplo

    inh = gtk_application_inhibit (app,
    NULL, GTK_APPLICATION_INHIBIT_LOGOUT |
    GTK_APPLICATION_INHIBIT_SUSPEND,
    "run the overnight jobs");
    
    • 1

relate perguntas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Existe um comando para listar todos os usuários? Também para adicionar, excluir, modificar usuários, no terminal?

    • 9 respostas
  • Marko Smith

    Como excluir um diretório não vazio no Terminal?

    • 4 respostas
  • Marko Smith

    Como descompactar um arquivo zip do Terminal?

    • 9 respostas
  • Marko Smith

    Como instalo um arquivo .deb por meio da linha de comando?

    • 11 respostas
  • Marko Smith

    Como instalo um arquivo .tar.gz (ou .tar.bz2)?

    • 14 respostas
  • Marko Smith

    Como listar todos os pacotes instalados

    • 24 respostas
  • Martin Hope
    Flimm Como posso usar o docker sem sudo? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    led-Zepp Como faço para salvar a saída do terminal em um arquivo? 2014-02-15 11:49:07 +0800 CST
  • Martin Hope
    ubuntu-nerd Como descompactar um arquivo zip do Terminal? 2011-12-11 20:37:54 +0800 CST
  • Martin Hope
    TheXed Como instalo um arquivo .deb por meio da linha de comando? 2011-05-07 09:40:28 +0800 CST
  • Martin Hope
    Ivan Como listar todos os pacotes instalados 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    David Barry Como determino o tamanho total de um diretório (pasta) na linha de comando? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher "Os seguintes pacotes foram retidos:" Por que e como resolvo isso? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford Como os PPAs podem ser removidos? 2010-07-30 01:09:42 +0800 CST

Hot tag

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve