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

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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

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

Ответ 3

Полная командная строка

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

В системах SunOS, если вы хотите получить полную командную строку, вы можете использовать

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

Чтобы получить полную командную строку, вам нужно стать суперпользователем.

Список аргументов

pargs -a PROCESS_ID

предоставит подробный список аргументов, переданных процессу. Он выведет массив аргументов следующим образом:

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

Я не нашел подобной команды для Linux, но я использовал бы следующую команду, чтобы получить похожий вывод:

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

Ответ 4

В Linux

cat /proc/<pid>/cmdline

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

Ответ 5

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

pgrep -l -f PatternOfProcess

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

Ответ 6

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

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

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

Ответ 7

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

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

Ответ 8

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

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

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

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

Ответ 9

В Solaris

     ps -eo pid,comm

аналогичные могут быть использованы в системах типа unix.

Ответ 10

В 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) -release) и без gnu userland:

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

Ответ 11

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

ps -o args= -f -p ProcessPid

Ответ 12

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

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

  1. Программа запускает процессы.

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

Ответ 13

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

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