Wie die Befehlszeile args an einen laufenden Prozess auf Unix / Linux-Systemen übergeben bekommen?
Frage
Auf SunOS gibt es pargs
Befehl, der die Befehlszeilenargumente druckt an den laufenden Prozess übergeben.
Gibt es irgendeinen ähnlichen Befehl auf anderen Unix-Umgebungen?
Lösung
Es gibt mehrere Möglichkeiten:
ps -fp <pid>
cat /proc/<pid>/cmdline | sed -e "s/\x00/ /g"; echo
Es gibt weitere Informationen in /proc/<pid>
auf Linux, hat nur einen Blick.
Auf anderen Unix-Varianten Dinge anders sein könnte. Der ps
Befehl überall funktionieren wird, ist die /proc
Sachen OS spezifisch. Zum Beispiel auf AIX gibt es keine cmdline
in /proc
.
Andere Tipps
Dies wird den Trick tun:
xargs -0 < /proc/<pid>/cmdline
Ohne die xargs, gibt es keine Leerzeichen zwischen den Argumenten, weil sie zu NULs umgewandelt wurden.
Vollkommandozeile
Für Linux & Unix-System können Sie ps -ef | grep process_name
verwenden Sie die vollständige Befehlszeile zu erhalten.
Auf SunOS Systemen, wenn Sie die volle Befehlszeile erhalten möchten, können Sie
/usr/ucb/ps -auxww | grep -i process_name
Um die volle Befehlszeile erhalten Sie Superuser zu werden brauchen.
Liste der Argumente
pargs -a PROCESS_ID
Eine detaillierte Liste von Argumenten gibt ein Verfahren geführt. Gibt er das Array von Argumenten wie folgt aus:
argv[o]: first argument
argv[1]: second..
argv[*]: and so on..
Ich habe keinen ähnlichen Befehl für Linux finden, aber ich würde den folgenden Befehl verwendet ähnliche Ausgabe zu erhalten:
tr '\0' '\n' < /proc/<pid>/environ
Ein Linux
cat /proc/<pid>/cmdline
get ist Sie die Kommandozeile des Prozesses (einschließlich args), aber mit allen Leerzeichen geändert NUL-Zeichen.
Sie können pgrep
mit -f
(Vollkommandozeile) und -l
(lange Beschreibung) verwenden:
pgrep -l -f PatternOfProcess
Dieses Verfahren hat einen entscheidenden Unterschied mit einem der anderen Antworten: es funktioniert auf CygWin , so dass Sie es zu erhalten, die vollständige Befehlszeile eines beliebigen Prozess läuft unter Windows (ausführen als erhöht , wenn Sie Daten über jeden erhöhten / admin Prozess wollen). Jede andere Methode, dies zu tun auf Windows ist umständlicher, zum Beispiel .
Außerdem: in meinen Tests hat sich die Art und Weise pgrep gewesen das einzige System, das funktioniert den vollständigen Pfad für Skripte erhalten innerhalb CygWin Python läuft
Eine andere Variante der Druck /proc/PID/cmdline
mit Leerzeichen in Linux ist:
cat -v /proc/PID/cmdline | sed 's/\^@/\ /g' && echo
Auf diese Weise cat
druckt NULL-Zeichen als ^@
und man sie dann mit einem Leerzeichen ersetzen mit sed
; echo
druckt eine neue Zeile.
Anstatt mehrere Befehle mit dem Strom zu bearbeiten, verwenden Sie nur ein - tr übersetzt ein Zeichen nach dem anderen:
tr '\0' ' ' </proc/<pid>/cmdline
Zusätzlich zu allen oben genannten Möglichkeiten, um den Text zu konvertieren, wenn Sie einfach ‚Strings‘ verwenden, wird die Ausgabe auf separate Zeilen standardmäßig machen. Mit dem zusätzlichen Vorteil, dass sie auch alle Zeichen verhindern, dass Ihr Terminal erscheinen Gerangel kann.
Beide Ausgang in einem Befehl:
Strings / proc // cmdline / proc // environ
Die eigentliche Frage ist ... Gibt es eine Möglichkeit, die reale Befehlszeile eines Prozesses in Linux, um zu sehen, die verändert wurden, so dass die cmdline den veränderten Text anstelle des tatsächlichen Befehl enthält, ausgeführt wurde.
Unter Solaris
ps -eo pid,comm
ähnlich kann auf Unix-ähnlichen Systemen verwendet werden.
Unter Linux mit bash, zur Ausgabe als zitierte args, so dass Sie den Befehl bearbeiten und erneut ausführen es
</proc/"${pid}"/cmdline xargs --no-run-if-empty -0 -n1 \
bash -c 'printf "%q " "${1}"' /dev/null; echo
Unter Solaris mit bash (getestet mit 3.2.51 (1) -release) und ohne 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-Beispiel (Paste in Terminal):
{
## 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
}
Ausgabe:
MATCH
Solaris Bash Beispiel:
{
## 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
}
Ausgabe:
MATCH
Sie können einfach verwenden:
ps -o args= -f -p ProcessPid
versuchen "ps -n" in einem Linux-Terminal. dies zeigt:
1. Alle laufenden Prozesse, ihre Kommandozeile und ihre PIDs
- Das Programm intiate die Prozesse.
Danach wissen Sie, welcher Prozess zu töten
Wenn Sie eine lange as möglich erhalten möchten (nicht sicher, welche Grenzen es gibt), ähnlich wie Solaris' pargs , können Sie dies auf Linux & OSX verwenden:
ps -ww -o pid,command [-p <pid> ... ]