Как получить args командной строки, переданные запущенному процессу в системах unix/linux?

на SunOS есть pargs команда, которая печатает аргументы командной строки, переданные запущенному процессу.

есть ли аналогичная команда в других средах Unix?

12 ответов


есть несколько вариантов:

ps -fp <pid>
cat /proc/<pid>/cmdline

есть больше информации в /proc/<pid> в Linux, просто посмотрите.

на других Униксах все может быть по-другому. The ps команда будет работать везде,/proc материал специфичен для ОС. Например на AIX нет cmdline на /proc.


это сделает трюк:

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

без xargs не будет пробелов между аргументами, потому что они были преобразованы в нули.


для Linux и Unix системы вы можете использовать ps -ef | grep process_name получить полную командную строку

в системе SunOS, если вы хотите получить полную командную строку, вы можете использовать /usr/ucb/ps -auxww | grep -i process_name. Убедитесь, что в SunOSto получите полную командную строку, вам нужно стать супер пользователем.

pargs -a PROCESS_ID. Это даст подробный список аргументов, переданных процессу. Это даст массив аргументов в выходных данных, таких как argv[o]: первый аргумен аргумент argv[1]: второй.. так далее..

Я не нашел подобной команды, но я дал бы следующую команду, чтобы получить такой выход tr '' '\n' < /proc/<pid>/environ в среде Linux.


On Linux

cat /proc/<pid>/cmdline

get вы командная строка процесса (включая args), но со всеми пробелами, измененными на символы NUL.


можно использовать pgrep С -f (полная командная строка) и -l (полное описание):

pgrep -l -f PatternOfProcess

этот метод имеет решающее отличие от любого другого ответа: он работает на CygWin, поэтому вы можете использовать его для получения полной командной строки любого процесса, запущенного под Windows (execute as возведен если вам нужны данные о каком-либо повышенном/административном процессе). Любой другой метод для этого в Windows более неудобен,для пример.
Кроме того: в моих тестах путь pgrep был единственная система, которая работала чтобы получить полный путь для скрипты, работающие внутри python CygWin.


другой вариант печати /proc/PID/cmdline с пробелами в Linux-это:

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

таким образом cat печать нулевые символы as ^@ и затем замените их с помощью sed; echo печатает символ новой строки.


в дополнение ко всем вышеперечисленным способам преобразования текста, если вы просто используете "строки", он будет делать вывод на отдельных строках по умолчанию. С дополнительным преимуществом, что он также может предотвратить появление любых символов, которые могут скремблировать ваш терминал.

оба вывода в одной команде:

строки / proc //cmdline/proc / / environ

реальный вопрос... есть ли способ увидеть реальную командную строку процесса в Linux, которая была изменена так, чтобы cmdline содержит измененный текст вместо фактической команды, которая была запущена.


На Солярисе

     ps -eo pid,comm

подобное можно использовать в unix-подобных системах.


в Linux, с bash, для вывода в виде цитируемых args, чтобы вы могли редактировать команду и перезапускать ее

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

на Solaris, с bash (протестировано с 3.2.51 (1)-release) и без gnu userland:

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

пример Linux 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" $'0' $'2' "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 " ""' /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
}

выход:

MATCH

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" $'0' $'2' "need" "quot"$'\t'"ing" )

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

declare -p tmpargs
eval_me=$(
    printf "argv_recovered=( "
    IFS=$'2' tmpargs=( $( pargs "${!}" \
        | /usr/bin/sed -n 's/^argv\[[0-9]\{1,\}\]: //gp' \
        | tr '\n' '2' ) )
    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
}

выход:

MATCH

вы можете просто использовать:

ps -o args= -f -p ProcessPid

вместо того, чтобы использовать несколько команд для редактирования потока, просто используйте one-tr переводит один символ в другой:

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

попробуйте "ps-n" в терминале linux. это покажет:

1.Все процессы запущены, их командная строка и их PIDs

  1. программа инициирует процессы.

после этого вы будете знать, какой процесс убить