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

203

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

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

Hemant
источник
4
tr \\0 ' ' < /proc/<pid>/cmdline
Дмитрий Григорьев

Ответы:

307

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

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

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

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

markus_b
источник
49
в Linux вам, вероятно, понадобится -ww (то есть ps -ww -fp <pid>), чтобы указать широкий вывод, так как, если есть несколько команд, они могут быть обрезаны.
Silfheed
2
-wwопция позволяет получить доступ к полным аргументов командной строки (столько же , сколько хранится в ядре). См. Также: как solaris и bsd получают необработанные параметры командной строки для процесса и параметры ps
GuruM
3
cat /proc/<pid>/cmdlineтакже работает на Cygwin, где аргументы строки cmd не отображаются psни с одним параметром.
Лечуп
3
В Linux, если вам нужно только получить команду args, ps -o args -p <pid>она будет и будет печатать argsили использовать -o cmd, только если вам нужно увидеть cmd. Попытка чтения /proc/<pid>/cmdlineне всегда работает для непривилегированных пользователей. psУтилита будет работать.
alvits
2
Подсказка: длина /proc/<pid>/cmdlineограничена (жестко запрограммирована на значение параметра ядра PAGE_SIZE), поэтому более длинные командные строки по-прежнему отображаются усеченными! См. Stackoverflow.com/questions/199130/… для получения дополнительной информации. Вы можете запросить настройки вашего ядра с помощью getconf PAGE_SIZE, обычно это
4096.
61

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

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

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

Майкл Беклинг
источник
3
Это может быть сокращено до xargs -0 < /proc/<pid>/cmdline.
СЛМ
Это все еще обрезает мой вывод. Любой совет?
Johnsam
Никогда не замечал каких-либо усечений - можете привести пример?
Майкл Беклинг
Таким образом, вы не можете сказать, является ли это встроенным пространством или границей аргумента.
ivan_pozdeev
19

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

Для Linux & Unix System вы можете использовать, 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
LOGAN
источник
14

В линуксе

cat /proc/<pid>/cmdline

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

Лотар
источник
3
Пробелы не удаляются, они заменяются NUL.
bdonlan
@bdonlan Ах, я не проверял это. Хороший улов!
Лотар
4
xargs -0 echo </ proc / <pid> / cmdline. Вы также можете сделать это с / proc / <pid> / environment, хотя вы можете добавить -n 1 для этого.
Camh
В моей системе нет файловой системы / proc :( любое другое решение?
Hemant
Мой процесс Java с длинными и длинными параметрами. Это все еще обрезает мой вывод. Любой совет?
Johnsam
14

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

pgrep -l -f PatternOfProcess

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

Сопалахо де Арриерес
источник
На самом деле это также печатает оригинальное имя исполняемого файла:$ exec -a fakename bash & [1] 14102 [1]+ Stopped exec -a fakename bash $ xargs -0 < /proc/14102/cmdline; fakename $ pgrep -l -f fakename; 14102 bash
unhammer
Не работает для меня, используя pgrep from procps-ng 3.3.15и 3.3.12. Просто печатает pid и prorgam name без аргументов.
Socowi
4

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

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

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

Диего
источник
К вашему сведению, вы также можете использовать cat -v / proc / PID / cmdline | sed 's / \ ^ @ / \ n / g' . Это заменит нулевой символ символом новой строки. При этом каждый аргумент будет напечатан в отдельной строке. Таким образом, легче отличить один аргумент от другого.
TSJNachos117
2

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

ps -o args= -f -p ProcessPid
Mitar
источник
2

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

tr '\0' ' ' </proc/<pid>/cmdline
Том Эванс
источник
1

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

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

strings / proc // cmdline / proc // environment

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

Тимоти Дж. Биггс
источник
1

На солярисе

     ps -eo pid,comm

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

HuntM
источник
1

В 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
Иван Аукамп
источник
0

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

ps -ww -o pid,command [-p <pid> ... ]
pourhaus
источник
-1

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

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

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

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

repzero
источник