A aplicação baseada em GUI executa comandos shell em segundo plano?

29

Eu migrei para o Ubuntu 16.04 há apenas 2 dias do Windows. Eu gosto da maneira como podemos personalizar o Unity Desktop. Estou apenas brincando com a aparência do ambiente Desktop. Assim como no Windows, eu queria que o lançador estivesse na parte inferior da tela. No Googling, encontrei um comando que diz:

gsettings set com.canonical.Unity.Launcher launcher-position Bottom

Além disso, há a ferramenta unity-tweak-tool e o editor dconf para fazer o trabalho. Mas estas são a abordagem GUI de fazer as coisas.

Minhas perguntas são:

  • Esses aplicativos baseados em GUI também executam o mesmo comando em segundo plano?
  • Como dar uma espiada no funcionamento interno dessas aplicações? Quer dizer, existe alguma maneira de realmente observar os comandos que estão sendo executados a cada clique do botão?
  • Esses aplicativos abrem um terminal em segundo plano e executam esses comandos?

A resposta aqui diz como chegar o descritor de arquivo padrão do processo. Mas eu não consegui nada na saída.

Além disso, o comando strace -p pid -o output.txt gera uma enorme quantidade de texto no arquivo.

Então, em suma, está fazendo coisas usando aplicativos GUI da mesma forma que fazendo coisas a partir da linha de comando?

    
por Logan 14.11.2016 / 12:52

2 respostas

35

Do these GUI-based applications also execute the same command in the background?

Sim e não. Eles escrevem no banco de dados dconf de configurações, mas podem estar usando maneiras diferentes de fazer isso. Programas escritos em Python provavelmente usarão o módulo gi.repository.Gio (eu sei porque eu uso muito) ou eles podem usar gsettings como um comando externo chamando subprocess.Popen(['gsettings','org.some.schema','some-key','value']) , e ele basicamente será executado como um comando shell. Um programa em C usará algo semelhante, provavelmente uma biblioteca gio.h , ou pode até usar a família de funções exec() para fazer o mesmo que o Popen em python. Então, para responder à sua pergunta do título: "O aplicativo baseado em GUI executa comandos shell em segundo plano?" Eles podem, mas provavelmente não é necessário porque há uma biblioteca para qualquer linguagem em que o aplicativo é escrito, e provavelmente será um pouco mais rápido usar uma função de biblioteca, do que gerar um novo processo.

Para dar uma amostra de como é feito com bibliotecas / módulos, sinta-se à vontade para dar uma olhada no código-fonte do meu indicador da lista de ativadores. Eu escrevi uma função para criar uma instância da classe Gio.Settings e usá-la para modificar o iniciador do Unity, dependendo do tipo de lista que você deseja ter.

How to have a peep at the internal working of these applications? I mean, is there any way of actually looking at the commands that are being executed at every click of button?

Não. Se você quiser ver qual comando é emitido na linguagem de programação do aplicativo, ao pressionar um botão ou clicar nos elementos da janela, não será possível. Leia o código-fonte do aplicativo, se for possível obtê-lo. Você pode usar dconf watch / para ver quais configurações estão sendo alteradas, mas não como isso é feito.

Tecnicamente, se você souber como operar um depurador, ler endereços de memória e conhecer alguma linguagem de montagem, saberá o que um aplicativo faz no nível de CPU e memória. Isso é conhecido como engenharia reversa de software e é freqüentemente usado por profissionais de segurança para analisar softwares mal-intencionados e descobrir vulnerabilidades em softwares legítimos.

Do these applications open up a terminal in the background and execute these commands?

Não, não há terminal conectado. Muitos programas sabem onde o banco de dados dconf do usuário está localizado e escrevem lá. Há também um barramento de comunicação entre processos conhecido como dbus , onde os programas podem enviar sinais e um programa como "Ei, essa é uma mensagem para mim!"

Adendo

  • As aplicações podem executar outras aplicações? Sim, isso é feito por meio de chamadas de sistema padrão fork() e execve() . A essência da criação de processos no Linux e em outros sistemas * nix é amplamente baseada nesses dois. O mecanismo do shell para executar comandos não embutidos usa muito em particular. Quando você corre interativamente

    $ ls 
    

    o shell criará um novo processo via fork() , esse processo executará execve() , que iniciará ls . Por causa de como execve() esse novo processo bifurcado será ls . A chamada do sistema pipe() é o que ajudará a ler a saída de ls . Eu sugiro strongmente ler minha resposta para Qual é a diferença entre pipe e redirecionamento para entender como o mecanismo de pipe funciona - não é só | operator, mas na verdade um syscall.

  • Os aplicativos podem executar comandos do shell? Não. A sintaxe da shell só é entendida pela própria shell. O que você pode fazer, no entanto, é iniciar um shell com um comutador -c da linha de comandos e fornecer comandos apropriados. Isso geralmente é usado para atalhos personalizados definidos no GNOME ou em outros ambientes de área de trabalho, já que atalhos personalizados operam em executáveis e não há shell para entender a sintaxe. Assim, como exemplo, você executaria bash -c 'xdotool key Ctrl+Alt+T' para executar indiretamente o comando xdotool ou bash -c 'cd $HOME/Desktop; touch New_File' para criar um novo arquivo na área de trabalho por meio de um atalho. Este é um exemplo particularmente interessante, pois você pode usar uma variável shell, já que você está usando um shell explicitamente.

por Sergiy Kolodyazhnyy 14.11.2016 / 13:04
21

Espionando o que acontece

A maioria do que esses editores de configurações fazem pode ser assistida executando

dconf watch /

em um terminal.

gsettings

Além disso, na maioria das vezes, para alcançar o que você vê acontecendo com o comando acima, esses aplicativos precisarão editar o banco de dados dconf (mais abaixo). Isso pode ser feito diretamente , usando as opções cli do dconf (que não é o preferido ), ou executando os comandos gsettings correspondentes, como o que você mencionou.

Para executar esses comandos, nenhuma janela de terminal é necessária, como você pode ver nos exemplos.

Sobre, gsettings, dconf e o banco de dados dconf

gsettings é o front end do cli para dconf , que por sua vez edita o banco de dados dconf , onde a maioria das configurações são armazenadas, em formato binário. Veja também esta boa resposta .

O banco de dados dconf , a propósito, também pode ser editado a partir da GUI por dconf editor, que está nos repositórios:

Amostrasdetrabalho

a.Empython

Paramostraroqueacontecesobocapô,abaixodeumaamostradetrabalhoparaalternaraposiçãodolançadordaGUIemumúnicobotão(alternar):

#!/usr/bin/env python3 import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk import subprocess key = ["com.canonical.Unity.Launcher", "launcher-position"] class ToggleWin(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title="Toggle") button = Gtk.Button("Toggle launcherposition") button.connect("clicked", self.toggle) self.add(button) def toggle(self, *args): # read the current setting on launcher position current = subprocess.check_output([ "gsettings", "get", key[0], key[1] ]).decode("utf-8").strip() # toggle to the other option new = "'Left'" if current == "'Bottom'" else "'Bottom'" subprocess.Popen([ "gsettings", "set", key[0], key[1], new ]) def delete_actions(*args): Gtk.main_quit() def miniwindow(): window = ToggleWin() window.connect("destroy", delete_actions) window.show_all() Gtk.main() miniwindow()
  • Cole o código em um file.py vazio
  • execute-o pelo comando:

    python3 /path/to/file.py
    

... e divirta-se.

b. Ícone do iniciador

Até mesmo um lançador simples pode fazer o trabalho na GUI:

[DesktopEntry]Name=SetlauncherpositionExec=zenity--info--text="Right- click to set launcher position"
Type=Application
StartupNotify=False
Icon=preferences-system

Actions=Launcher to bottom;Launcher on the left;

[Desktop Action Launcher to bottom]
Name=Launcher to bottom
# right click option to set launcher to bottom
Exec=gsettings set com.canonical.Unity.Launcher launcher-position Bottom

[Desktop Action Launcher on the left]
Name=Launcher on the left
# right click option to set launcher to left
Exec=gsettings set com.canonical.Unity.Launcher launcher-position Left
  • Cole o código em um arquivo vazio, salve-o como setlauncher.desktop
  • Arraste-o para o iniciador e clique com o botão direito em

Para uso permanente, armazene-o em ~/.local/share/applications (para uso local) ou ~/usr/share/applications para todos os usuários.

    
por Jacob Vlijm 14.11.2016 / 12:56