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

StackOverflow https://stackoverflow.com/questions/821837

Pergunta

Em SunOS há comando pargs que imprime os argumentos de linha de comando passados ??para o processo em execução.

Existe algum comando similar em outros ambientes Unix?

Foi útil?

Solução

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> no Linux, basta ter um olhar.

Em outras coisas unixes pode ser diferente. O comando ps irá funcionar em todos os lugares, o material /proc é OS específico. Por exemplo, em AIX não há cmdline em /proc.

Outras dicas

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 para NULs.

completa linha de comando

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

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

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

Para obter a linha de comando completa que você precisa para se tornar super-usuário.

Lista de argumentos

pargs -a PROCESS_ID

lhe dará uma lista detalhada dos argumentos passados ??para um processo. A saída será a matriz de argumentos como este:

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

Eu não encontrou qualquer comando semelhante para Linux, mas eu usaria o seguinte comando para obter uma saída semelhante:

tr '\0' '\n' < /proc/<pid>/environ

Em Linux

cat /proc/<pid>/cmdline

get é-lhe o comando do processo (incluindo args), mas com todos os espaços em branco alterado para caracteres NUL.

Você pode usar pgrep com -f (linha de comando completo) e -l (descrição longa):

pgrep -l -f PatternOfProcess

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

.

Outra variante de imprimir /proc/PID/cmdline com espaços em Linux é:

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

Desta forma cat impressões caracteres NULL como ^@ e então você substituí-los com um espaço usando sed; echo imprime uma nova linha.

Ao invés de usar vários comandos para editar o fluxo, basta usar um - tr traduz um personagem para outro:

tr '\0' ' ' </proc/<pid>/cmdline

Além de todas as maneiras acima para converter o texto, se você simplesmente usar 'cordas', ele vai fazer a saída em linhas separadas por padrão. Com a vantagem adicional de que ele também pode prevenir quaisquer caracteres que podem embaralhar seu terminal de aparecer.

Tanto a saída em um comando:

cordas / proc // cmdline / proc // environ

A verdadeira questão é ... há uma maneira de ver a linha de comando real de um processo no Linux que tenha sido alterado para que o cmdline contém o texto alterado em vez do comando real que foi executado.

No Solaris

     ps -eo pid,comm

semelhante pode ser usado em Unix como sistemas.

No Linux, com bash, a saída como argumentos citados 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 festa (testado com 3.2.51 (1) -release) e sem userland 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 Linux festa (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
}

Output:

MATCH

Solaris Bash Exemplo:

{
## 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
}

Output:

MATCH

Você pode simplesmente usar:

ps -o args= -f -p ProcessPid

try "ps -n" em um terminal linux. isso vai mostrar:

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

  1. O programa intiate os processos.

Depois você vai saber qual processo para matar

Se você deseja obter uma longa-como-possível (não tenho certeza de que limites existem), semelhante ao Solaris' pargs , você pode usar isso em Linux e OSX:

ps -ww -o pid,command [-p <pid> ... ]
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top