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 / unix / Perguntas / 775286
Accepted
k.schroeder31
k.schroeder31
Asked: 2024-04-27 00:02:31 +0800 CST2024-04-27 00:02:31 +0800 CST 2024-04-27 00:02:31 +0800 CST

Por que um comando process ps mostra espaços em torno de um diretório em vez de barras?

  • 772

Estou tentando depurar um monitor de processo legado com falha que pesquisa processos em execução. Eu determinei que isso está sendo causado por algum comportamento misterioso do Linux. O processo que está sendo executado é /opt/my/path/directoryname/daemonname, mas por algum motivo estranho, ele aparece com espaços, não /, ao redor do nome do diretório. Muitos daemons estão sendo executados no mesmo diretório e aparecem com o caminho correto. É apenas um daemon específico em cada servidor.

ps -efmostra o seguinte para este daemon:

/opt/my/path directoryname daemonname --arg1 VALUE1 --arg-two VALUE.TWO --arg-three ARG.UMENT.THREE.ERR --worker daemonname --pid-role daemonname

Este daemon está sendo iniciado por um script perl. Comparando-o com outros, parece que o caminho do diretório está sendo fornecido usando exatamente a mesma variável env de todos os outros scripts, mas esses outros scripts resultam em um caminho correto como /opt/my/path/directoryname/daemonname. As linhas Perl relevantes se parecem com exec => catfile( $settings->config("/directories/executables"), $daemon_name ),e eu confirmei que o valor de config("/directories/executables") é o valor correto/opt/my/path/directoryname

Procurar por esta pergunta tem sido um pesadelo devido a todas as perguntas sobre nomes de diretórios com espaços. Isto não é isso. Nenhum caminho deve conter um espaço. ps mostra meu comando mkdir com um espaço onde eu tinha uma barra é o mais próximo que consegui encontrar, que não foi respondido.

perl
  • 1 1 respostas
  • 293 Views

1 respostas

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2024-04-27T02:21:11+08:002024-04-27T02:21:11+08:00

    Entre os campos retornados por ps -festá a lista de argumentos passados ​​para a última execução do comando que o processo (ou um de seus ancestrais) realizou. Você pode conseguir exatamente isso com ps -o args.

    Quando um processo executa um arquivo, isso ocorre com a execve()chamada do sistema:

    execve("/path/to/executable", [arg0, arg1..., 0], [env1, env2... 0])
    

    arg0por convenção é o nome do executável. Quando um shell interpreta um:

    cmd arg
    

    linha de comando, ele chama execve("/path/to/cmd", ["cmd", "arg", 0], ...). Quando isso é:

    /path/to/cmd arg
    

    Ele chama execve("/path/to/cmd", ["/path/to/cmd", "arg", 0], ...).

    Essas strings ( cmd, arg) terminam na parte inferior da pilha do processo, delimitadas por NUL. Dentro do processo, é isso que argv[0]... argv[1]aponta.

    No Linux, essa área é exposta em /proc/<pid>/cmdline, e é daí psque vem para o argscampo.

    Tecnicamente, pspega essa lista de strings e imprime-a unida com espaços para que no final os argscampos se pareçam com a linha de comando do shell que seria usada para executar o comando.

    Aqui, se psmostra:

    /opt/my/path directoryname daemonname --arg1...
    

    Esses espaços podem indicar um espaço real nessas strings, ou strings separadas ou o fato de que os espaços foram substituídos por NULs nessas strings.

    O último é plausível se o processo usou a função padrãostrtok() ou uma abordagem semelhante para argv[0]dividi-lo, /possivelmente para descobrir o nome base do executável como ele foi executado ou os diferentes componentes do diretório de seu caminho.

    Por exemplo, se eu criar:

    #include <string.h>
    #include <unistd.h>
    int main(int argc, char *argv[])
    {
      strtok(argv[0], "/");
      while (strtok(NULL, "/"));
      pause();
    }
    

    E compile e execute:

    $ cc a.c
    $ "$PWD/a.out" &
    [1] 67758
    $ ps -fp "$!"
    UID          PID    PPID  C STIME TTY          TIME CMD
    chazelas   67758   60043  0 19:19 pts/4    00:00:00 /home chazelas a.out
    

    Você verá que os /s foram substituídos por espaços.

    Na verdade, eles foram substituídos por NULs, como pode ser verificado em:

    $ sed -n l "/proc/$!/cmdline"
    /home\000chazelas\000a.out\000$
    

    Mas psvi esses NULs e os interpretei como delimitadores para 3 argumentos diferentes que uniram com espaços.

    Então, supondo que essa seja a explicação correta, não é um comportamento estranho do Linux, é apenas o próprio aplicativo modificando-o argv[0]após ser iniciado (provavelmente substituindo /s por NULs, provavelmente para extrair alguns componentes do caminho).

    No Linux, uma maneira mais confiável de descobrir qual executável um processo está em execução no momento é executar um readlink()on /proc/<pid>/exe, por exemplo, com o utilitário realpathor readlinkou o statintegrado de zsh:

    $ zmodload zsh/stat
    $ stat +link /proc/$!/exe
    /home/chazelas/a.out
    $ readlink "/proc/$!/exe"
    /home/chazelas/a.out
    $ realpath "/proc/$!/exe"
    /home/chazelas/a.out
    

    E a implementação do procps psno Linux retorna com ps -o exe.

    Não existe uma maneira infalível de saber com certeza quais argumentos foram passados ​​para o comando, pois o que é mostrado /proc/<pid>/cmdlinepode ser modificado pelo processo.

    Os registros de auditoria podem conter as informações.

    • 10

relate perguntas

  • erro zabbix_sender

  • atualizações cpanm vs apt

  • Correspondência de pares reversíveis em um arquivo CSV

  • Perl: é possível usar a substituição de variável?

  • calcule a soma de cada 2 linhas e substitua-as por outro valor se a soma for menor que um valor específico

Sidebar

Stats

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

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

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