Como obter os argumentos da linha de comando passados ​​para um processo em execução nos sistemas unix / linux?

203

No SunOS, existe um pargscomando que imprime os argumentos da linha de comando passados ​​para o processo em execução.

Existe algum comando semelhante em outros ambientes Unix?

Hemant
fonte
4
tr \\0 ' ' < /proc/<pid>/cmdline
Dmitry Grigoryev

Respostas:

307

Existem várias opções:

ps -fp <pid>
cat /proc/<pid>/cmdline | sed -e "s/\x00/ /g"; echo

Há mais informações no /proc/<pid>Linux, basta dar uma olhada.

Em outros Unixes, as coisas podem ser diferentes. O pscomando funcionará em qualquer lugar, o /procmaterial é específico do sistema operacional. Por exemplo, em AIX não existe cmdlineno /proc.

markus_b
fonte
49
no linux, você provavelmente precisará de -ww (ie ps -ww -fp <pid>) para especificar uma saída ampla, pois se houver vários comandos, eles poderão ser cortados.
Silfheed 06/05/09
2
a -wwopção permite acesso a argumentos completos da linha de comando (o máximo que é armazenado pelo kernel). Veja também: como o solaris e o bsd obtêm os parâmetros da linha de comando não truncados para as opções de
#
3
cat /proc/<pid>/cmdlinetambém funciona no Cygwin, onde os argumentos da linha cmd não são mostrados pscom nenhuma opção.
Lechup
3
No Linux, se você precisar apenas obter o args, o comando é ps -o args -p <pid>e ele imprimirá apenas o comando args-ocmd se você precisar apenas ver o cmd. Tentar ler /proc/<pid>/cmdlinenem sempre funcionará para usuários sem privilégios. O psutilitário irá funcionar.
alvits
2
Dica: o comprimento de /proc/<pid>/cmdlineé limitado (codificado no valor do parâmetro PAGE_SIZE do kernel), portanto, linhas de comando mais longas ainda são mostradas truncadas! Consulte stackoverflow.com/questions/199130/… para obter mais informações. Você pode consultar a configuração do seu kernel getconf PAGE_SIZE, geralmente é 4096.
t0r0X
61

Isto irá fazer o truque:

xargs -0 < /proc/<pid>/cmdline

Sem os xargs, não haverá espaços entre os argumentos, porque eles foram convertidos em NULs.

Michael Böckling
fonte
3
Isso pode ser reduzido para xargs -0 < /proc/<pid>/cmdline.
SLM
Ainda está truncando minha saída. Algum conselho?
precisa saber é
Nunca notei nenhum truncamento - você pode dar um exemplo?
Michael Böckling 31/08/2015
Dessa forma, você não pode dizer se é um espaço embutido ou um limite de argumento.
ivan_pozdeev 28/04
19

Linha de comando completa

Para Linux e Unix System, você pode usar ps -ef | grep process_namepara obter a linha de comando completa.

Nos sistemas SunOS, se você deseja obter uma linha de comando completa, pode usar

/usr/ucb/ps -auxww | grep -i process_name

Para obter a linha de comando completa, você precisa se tornar superusuário.

Lista de argumentos

pargs -a PROCESS_ID

fornecerá uma lista detalhada de argumentos passados ​​para um processo. Ele produzirá a matriz de argumentos da seguinte maneira:

argv[o]: first argument
argv[1]: second..
argv[*]: and so on..

Não encontrei nenhum comando semelhante para Linux, mas usaria o seguinte comando para obter resultados semelhantes:

tr '\0' '\n' < /proc/<pid>/environ
LOGAN
fonte
14

No Linux

cat /proc/<pid>/cmdline

get é a linha de comando do processo (incluindo args), mas com todos os espaços em branco alterados para caracteres NUL.

Lothar
fonte
3
O espaço em branco não é removido, é substituído por NULs.
5159 bdonlan
Ah, eu não verifiquei isso. Boa pegada!
5309 lothar
4
xargs -0 eco </ proc / <pid> / cmdline. Você também pode fazer isso com / proc / <pid> / environ também, embora queira adicionar -n 1 para isso.
Camh 5/05
No meu sistema não há proc filesystem :( qualquer outra solução /?
Hemant
O meu é um processo java com parâmetros muito longos. Ainda está truncando minha saída. Algum conselho?
precisa saber é
14

Você pode usar pgrepcom -f(linha de comando completa) e -l(descrição longa):

pgrep -l -f PatternOfProcess

Este método tem uma diferença crucial com qualquer uma das outras respostas: funciona no CygWin , para que você possa usá-lo para obter a linha de comando completa de qualquer processo em execução no Windows (execute como elevado se desejar dados sobre qualquer processo elevado / administrativo) . Qualquer outro método para fazer isso no Windows é mais complicado ( por exemplo ).
Além disso: nos meus testes, a maneira pgrep foi o único sistema que trabalhou para obter o caminho completo para scripts em execução no python do CygWin .

Sopalajo de Arrierez
fonte
Este realmente imprime o nome do executável original também:$ exec -a fakename bash & [1] 14102 [1]+ Stopped exec -a fakename bash $ xargs -0 < /proc/14102/cmdline; fakename $ pgrep -l -f fakename; 14102 bash
unhammer
Não funciona para mim usando pgrep from procps-ng 3.3.15e 3.3.12. Apenas imprime o nome pid e prorgam sem argumentos.
Socowi 20/09/19
4

Outra variante de impressão /proc/PID/cmdlinecom espaços no Linux é:

cat -v /proc/PID/cmdline | sed 's/\^@/\ /g' && echo

Dessa forma, catimprime caracteres NULL como ^@e, em seguida, você os substitui por um espaço usando sed; echoimprime uma nova linha.

Diego
fonte
Para sua informação, você também pode usar cat -v / proc / PID / cmdline | \ 's / \ n / g' de sed . Isso substituirá o caractere nulo por um caractere de nova linha. Ao fazer isso, cada argumento será impresso em sua própria linha. Dessa forma, é mais fácil distinguir um argumento de outro.
TSJNachos117
2

Você pode simplesmente usar:

ps -o args= -f -p ProcessPid
Mitar
fonte
2

Em vez de usar vários comandos para editar o fluxo, use apenas um - tr converte um caractere para outro:

tr '\0' ' ' </proc/<pid>/cmdline
Tom Evans
fonte
1

Além de todas as maneiras acima para converter o texto, se você simplesmente usar 'strings', ele produzirá a saída em linhas separadas por padrão. Com o benefício adicional, ele também pode impedir a exibição de caracteres que possam embaralhar seu terminal.

Ambos emitem em um comando:

strings / proc // cmdline / proc // environ

A verdadeira questão é ... existe uma maneira de ver a linha de comando real de um processo no Linux que foi alterada para que o cmdline contenha o texto alterado em vez do comando real que foi executado.

Timothy J. Biggs
fonte
1

No Solaris

     ps -eo pid,comm

similar pode ser usado em sistemas como o Unix.

HuntM
fonte
1

No Linux, com bash, para produzir como args entre aspas, para que você possa editar o comando e executá-lo novamente

</proc/"${pid}"/cmdline xargs --no-run-if-empty -0 -n1 \
    bash -c 'printf "%q " "${1}"' /dev/null; echo

No Solaris, com bash (testado com a versão 3.2.51 (1)) e sem a terra do usuário do gnu:

IFS=$'\002' tmpargs=( $( pargs "${pid}" \
    | /usr/bin/sed -n 's/^argv\[[0-9]\{1,\}\]: //gp' \
    | tr '\n' '\002' ) )
for tmparg in "${tmpargs[@]}"; do
    printf "%q " "$( echo -e "${tmparg}" )"
done; echo

Exemplo de Linux bash (cole no terminal):

{
## setup intial args
argv=( /bin/bash -c '{ /usr/bin/sleep 10; echo; }' /dev/null 'BEGIN {system("sleep 2")}' "this is" \
    "some" "args "$'\n'" that" $'\000' $'\002' "need" "quot"$'\t'"ing" )

## run in background
"${argv[@]}" &

## recover into eval string that assigns it to argv_recovered
eval_me=$(
    printf "argv_recovered=( "
    </proc/"${!}"/cmdline xargs --no-run-if-empty -0 -n1 \
        bash -c 'printf "%q " "${1}"' /dev/null
    printf " )\n"
)

## do eval
eval "${eval_me}"

## verify match
if [ "$( declare -p argv )" == "$( declare -p argv_recovered | sed 's/argv_recovered/argv/' )" ];
then
    echo MATCH
else
    echo NO MATCH
fi
}

Resultado:

MATCH

Exemplo do Solaris Bash:

{
## setup intial args
argv=( /bin/bash -c '{ /usr/bin/sleep 10; echo; }' /dev/null 'BEGIN {system("sleep 2")}' "this is" \
    "some" "args "$'\n'" that" $'\000' $'\002' "need" "quot"$'\t'"ing" )

## run in background
"${argv[@]}" &
pargs "${!}"
ps -fp "${!}"

declare -p tmpargs
eval_me=$(
    printf "argv_recovered=( "
    IFS=$'\002' tmpargs=( $( pargs "${!}" \
        | /usr/bin/sed -n 's/^argv\[[0-9]\{1,\}\]: //gp' \
        | tr '\n' '\002' ) )
    for tmparg in "${tmpargs[@]}"; do
        printf "%q " "$( echo -e "${tmparg}" )"
    done; echo
    printf " )\n"
)

## do eval
eval "${eval_me}"


## verify match
if [ "$( declare -p argv )" == "$( declare -p argv_recovered | sed 's/argv_recovered/argv/' )" ];
then
    echo MATCH
else
    echo NO MATCH
fi
}

Resultado:

MATCH
Iwan Aucamp
fonte
0

Se você deseja obter o máximo de tempo possível (sem saber quais são os limites), semelhante ao pargs do Solaris , você pode usá-lo no Linux e OSX:

ps -ww -o pid,command [-p <pid> ... ]
pourhaus
fonte
-1

tente ps -nem um terminal linux. Isso mostrará:

1.Todos os processos em execução , sua linha de comandos e seus PIDs

  1. O programa inicia os processos.

Depois você saberá qual processo matar

repzero
fonte