Jak przekazać argumenty wiersza poleceń do działającego procesu w systemach unix / linux?


202

W pargssystemie SunOS istnieje polecenie, które wypisuje argumenty wiersza poleceń przekazane do uruchomionego procesu.

Czy istnieje inne podobne polecenie w innych środowiskach uniksowych?


4
tr \\0 ' ' < /proc/<pid>/cmdline
Dmitrij Grigoriew

Odpowiedzi:


307

Istnieje kilka opcji:

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

Jest więcej informacji na /proc/<pid>temat Linuksa, wystarczy spojrzeć.

Na innych Uniksach może być inaczej. psKomenda będzie działać wszędzie, /procrzeczy jest OS specyficzny. Na przykład w systemie AIX nie ma cmdlinew /proc.


49
w systemie Linux prawdopodobnie potrzebujesz -ww (tj. ps -ww -fp <pid>), aby określić szeroki wynik, ponieważ jeśli istnieje kilka poleceń, mogą zostać odcięte.
Silfheed

2
-wwopcja umożliwia dostęp do pełnych argumentów wiersza polecenia (jak jest przechowywana przez jądro). Zobacz także: w jaki sposób solaris i bsd pobierają nieskalowane parametry wiersza polecenia dla procesu i opcji ps
GuruM

3
cat /proc/<pid>/cmdlinedziała również na Cygwin, gdzie argumenty linii cmd nie są wyświetlane w psżadnej opcji.
lechup

3
W Linuksie, jeśli potrzebujesz tylko args, polecenie to jest ps -o args -p <pid>i wypisze argslub użyje opcji -o, cmdjeśli tylko chcesz zobaczyć cmd. Próba czytania /proc/<pid>/cmdlinenie zawsze będzie działać dla nieuprzywilejowanych użytkowników. psNarzędzie będzie działać.
alvits

2
Wskazówka: długość /proc/<pid>/cmdlinejest ograniczona (zakodowana na stałe do wartości parametru jądra PAGE_SIZE), więc dłuższe linie poleceń są nadal pokazywane jako obcięte! Aby uzyskać więcej informacji, zobacz stackoverflow.com/questions/199130/ ... Możesz zapytać o ustawienia jądra getconf PAGE_SIZE, zwykle jest to 4096.
t0r0X

61

To załatwi sprawę:

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

Bez xargs między argumentami nie będzie spacji, ponieważ zostały one przekonwertowane na wartości NUL.


3
Można to skrócić xargs -0 < /proc/<pid>/cmdline.
slm,

Nadal obciąża moje wyjście. Jakaś rada?
johnsam

Nigdy nie zauważyłem żadnego obcięcia - czy możesz podać przykład?
Michael Böckling,

W ten sposób nie można powiedzieć, czy jest to wstawiana spacja czy granica argumentów.
ivan_pozdeev

19

Pełna linia poleceń

W przypadku systemu Linux i Unix można użyć, ps -ef | grep process_nameaby uzyskać pełny wiersz poleceń.

W systemach SunOS, jeśli chcesz uzyskać pełny wiersz poleceń, możesz użyć

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

Aby uzyskać pełną linię poleceń, musisz zostać superużytkownikiem.

Lista argumentów

pargs -a PROCESS_ID

poda szczegółową listę argumentów przekazanych do procesu. Wyświetli tablicę argumentów w następujący sposób:

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

Nie znalazłem żadnego podobnego polecenia dla systemu Linux, ale użyłbym następującego polecenia, aby uzyskać podobne dane wyjściowe:

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

14

W systemie Linux

cat /proc/<pid>/cmdline

dostajesz komendę procesu (łącznie z argumentami), ale wszystkie białe znaki zostały zmienione na znaki NUL.


3
Białe znaki nie są usuwane, są zastępowane wartościami NUL
bdonlan

@bdonlan Ah, nie sprawdziłem tego. Dobry chwyt!
lothar

4
xargs -0 echo </ proc / <pid> / cmdline. Możesz to również zrobić za pomocą / proc / <pid> / Environment, chociaż możesz chcieć dodać w tym celu opcję -n 1.
camh

W moim systemie nie ma systemu plików / proc :( jakieś inne rozwiązanie?
Hemant

Mój jest procesem Java z długimi, długimi, długimi parametrami. Nadal obciąża moje wyjście. Jakaś rada?
johnsam

14

Możesz używać pgrepz -f(pełnym wierszem poleceń) i -l(długim opisem):

pgrep -l -f PatternOfProcess

Ta metoda ma zasadniczą różnicę w stosunku do innych odpowiedzi: działa na CygWin , dzięki czemu można jej użyć do uzyskania pełnego wiersza polecenia dowolnego procesu działającego w systemie Windows (wykonaj jako podniesiony, jeśli chcesz danych o dowolnym podniesionym / administracyjnym procesie) . Każda inna metoda wykonywania tego w systemie Windows jest bardziej niewygodna ( na przykład ).
Ponadto: w moich testach sposób pgrep był jedynym systemem, który działał w celu uzyskania pełnej ścieżki dla skryptów działających w pythonie CygWin .


Ten faktycznie drukuje również oryginalną nazwę pliku wykonywalnego:$ 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

Nie działa dla mnie przy użyciu pgrep from procps-ng 3.3.15i 3.3.12. Wystarczy wydrukować nazwę pid i prorgam bez argumentów.
Socowi,

4

Innym wariantem drukowania /proc/PID/cmdlineze spacjami w systemie Linux jest:

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

W ten sposób catdrukuje znaki NULL jako, ^@a następnie zamieniasz je spacją za pomocą sed; echowypisuje nowy wiersz.


Do twojej wiadomości, możesz także użyć cat -v / proc / PID / cmdline | sed 's / \ ^ @ / \ n / g' . Spowoduje to zastąpienie znaku zerowego znakiem nowego wiersza. W ten sposób każdy argument zostanie wydrukowany w osobnej linii. W ten sposób łatwiej odróżnić jeden argument od drugiego.
TSJNachos117


2

Zamiast używać wielu poleceń do edycji strumienia, po prostu użyj jednego - tr tłumaczy jeden znak na inny:

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

1

Oprócz wszystkich powyższych sposobów konwersji tekstu, jeśli po prostu użyjesz „łańcuchów”, domyślnie utworzy on wyjście w osobnych wierszach. Z tą dodatkową zaletą, że może również zapobiegać pojawianiu się znaków, które mogą mieszać twój terminal.

Oba dane wyjściowe w jednym poleceniu:

strings / proc // cmdline / proc // environment

Prawdziwe pytanie brzmi ... czy istnieje sposób, aby zobaczyć prawdziwą linię komend procesu w Linuksie, która została zmieniona, tak aby cmdline zawierał zmieniony tekst zamiast faktycznie uruchomionej komendy.


1

W systemie Solaris

     ps -eo pid,comm

podobne mogą być stosowane w systemach uniksopodobnych.


1

W Linuksie, z bash, wyprowadza jako cytowane argumenty, aby można było edytować polecenie i uruchomić je ponownie

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

W Solarisie, z bash (testowany z wydaniem 3.2.51 (1)) i bez przestrzeni użytkownika 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 Przykład (wklej w terminalu):

{
## 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
}

Wynik:

MATCH

Przykład 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
}

Wynik:

MATCH

0

Jeśli chcesz uzyskać jak najdłużej (nie jestem pewien, jakie są ograniczenia), podobnie jak w systemach Solaris , możesz użyć tego w systemach Linux i OSX:

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

-1

spróbuj ps -nw terminalu Linux. To pokaże:

1. Wszystkie procesy RUNNING , ich linia poleceń i ich PID

  1. Program inicjuje procesy.

Następnie dowiesz się, który proces zabić

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.