Como obter os argumentos de linha de comando passados ??para um processo em execução em sistemas unix / linux?
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?
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
- 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> ... ]