Posso usar ferramentas padrão para obter o nome completo de um processo, quando o nome dele tiver espaços incorporados?

6

Eu entendo que pode ser uma situação rara para um executável ter espaços, mas isso pode acontecer.

Um exemplo pode ser a melhor explicação.

Usando ferramentas padrão, eu quero determinar a localização (no sistema de arquivos) do executável que possui (?) a janela atual ...

  1. obtenha o ID da janela atual ... ( xdotool getactivewindow)
  2. use o ID para obter o PID ... ( wmctrl -p -l | sed ... ID ....
  3. use o PID para obter o nome do executável ... ( ps -A ... aqui é onde eu me deparo com problemas!

Quando ps , ao listar apenas o nome do executável ( -o ucmd ), ele trunca o nome para 15 caracteres, portanto, isso exclui essa opção para qualquer nome que seja mais longo.
Alargar a coluna ( -o ucmd:99 ) não faz diferença .. Se pgrep for qualquer coisa, sua correspondência é limitada a 15 por causa de stat (consulte: info pgrep).

As listagens em variantes do modo "completo" (por exemplo, -A w w ) não são úteis quando o nome em questão tem espaços, porque esse nome é separado de seus argumentos por outro espaço ! Além disso, no modo "completo", se o processo foi iniciado por um link, o nome do link é mostrado, em vez do nome do executável.

Existe alguma maneira de fazer isso (usando ferramentas padrão)? ... ou são espaços um show stopper aqui?

    
por Peter.O 15.01.2011 / 12:36

2 respostas

7

Todos os utilitários obtêm suas informações de /proc/$PID de qualquer maneira, mas há (pelo menos) três lugares em /proc/$PID que contêm o nome do executável de alguma forma, e eles relatam informações diferentes.

  • O campo Name em /proc/$PID/status (também disponível em um formato mais difícil de analisar em /proc/$PID/stat ). Este é o nome do executável, mas truncado para 15 caracteres. Como o kernel executa o truncamento, nenhuma opção para ps pode ajudar. Isso é o que mostra ps -o comm (ou seu sinônimo ps -o ucmd ).
  • O link simbólico /proc/$PID/exename aponta para o arquivo executável. Você pode obter seu conteúdo com readlink /proc/$PID/exename . Ao contrário das informações relatadas por ps , apenas o usuário que está executando o processo tem permissão para ler o destino do link.
  • O argumento zeroth para o processo, conforme escolhido pelo shell ou outro programa que o invocou. Por convenção, os shells escolhem o nome do executável conforme você o digitou (com ou sem um caminho completo). Você pode obter todos os argumentos de ps com ps -o cmd (ou seu sinônimo ps -o command ), mas os argumentos são separados por espaços para que você não possa dizer com segurança onde o argumento zeroth para. Você pode ler os argumentos de /proc/cmdline , onde eles são separados por caractere nulo: </proc/$PID/cmdline awk -vRS='Name' '{print; exit;}' extrai o argumento zeroth.

Para completar, deixe-me mencionar que esses nomes podem mudar durante a vida útil do processo, embora a maioria dos programas não o faça:

  • O processo pode alterar o campo /proc/$PID/status de prctl chamando PR_SET_NAME com o argumento (deleted) .
  • O arquivo executável pode ser renomeado ou excluído. Em casos simples, o Linux controla o novo nome (mas os casos de borda podem não funcionar, por exemplo, se você criar um link físico para o executável). Se o arquivo for excluído, o kernel adicionará argv[0] ao destino do link.
  • O argumento zeroth para o processo é lido na memória do processo (é %code% em C). O processo pode modificá-lo livremente.
por Gilles 15.01.2011 / 18:07
0
ps $PID | tail -1 | awk '{i=5; while (i<NF) {printf "%s ", $i; i++}; print $NF}'

Onde $ PID é o PID que você tem. Provavelmente o comando completo que você quer (baseado na sua pergunta acima) é:

which "$(ps $(xdotool getwindowpid $(xdotool getactivewindow)) | tail -1 | awk '{i=5; while (i<NF) {printf "%s ", $i; i++}; print $NF}')"
    
por zpletan 15.01.2011 / 16:03