it-swarm.com.ru

Как передать аргументы командной строки в работающий процесс в системах Unix/Linux?

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

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

167
Hemant

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

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

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

В других Unixes все может быть иначе. Команда ps будет работать везде, материал /proc зависит от ОС. Например, в AIX нет cmdline в /proc.

264
markus_b

Это сделает свое дело:

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

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

58
Michael Böckling

On Linux

cat /proc/<pid>/cmdline

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

14
lothar

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

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

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

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

14
LOGAN

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

pgrep -l -f PatternOfProcess

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

12
Sopalajo de Arrierez

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

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

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

3
Diego

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

ps -o args= -f -p ProcessPid
1
Mitar

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

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

На Solaris, с bash (протестировано с 3.2.51 (1) -релизом) и без пользовательского пространства 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

Пример 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" $'\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
}

Результат:

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" $'\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
}

Результат:

MATCH
1
Iwan Aucamp

На солярисе

     ps -eo pid,comm

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

1
HuntM

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

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

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

Оба вывода в одну команду:

strings/proc // cmdline/proc // environment

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

1
Timothy J. Biggs

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

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

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

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

0
repzero

Если вы хотите получить максимально возможную длину (не знаете, какие существуют ограничения), аналогично pargs в Solaris, вы можете использовать это в Linux и OSX:

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