Linux hat ein /proc
Verzeichnis und ein Dateisystem, die, soweit ich das beurteilen kann, nicht Teil von POSIX sind. In jedem /proc/$PID
Unterverzeichnis befindet sich ein symbolischer Link, cwd
der auf das tatsächliche Arbeitsverzeichnis des Prozesses dieser PID verweist (der cwd
Link ist immer aktuell).
Diese symbolische Verknüpfung ist für einige Anwendungsfälle praktisch, z. B. das Arbeiten mit unterschiedlichen Shells und das Austauschen von Dateien zwischen den beiden Shells (formal deren Arbeitsverzeichnisse).
Gibt es eine einfache Möglichkeit, etwas Ähnliches zu erhalten, nur mit der POSIX-Funktion?
Mehr zur Frage
Nach einem Kommentar, mehr Präzision: Es muss nicht unbedingt ein Link und eine Umgebungsvariable sein $<PID>_CWD
, wäre auch so gut, obwohl ich auf den ersten Blick nicht glaube, dass es eine solche Lösung gibt. Es muss nur leicht zu referenzieren sein (z. B. symbolischer Link oder Umgebungsvariable) und jedes Mal auf dem neuesten Stand sein, wenn der andere Prozess das Arbeitsverzeichnis wechselt.
Die Lösung muss nicht unbedingt POSIX sein, und der wichtigste Aspekt ist die Portabilität, aber POSIX ist sicherlich eine Garantie.
pwdx
Befehl. Sie können also einfach einen Alias oder eine Funktion erstellen, diepwdx
unter Linux aufgerufen wird und sich umgibt,readlink
wenn Sie nach etwas Tragbarem suchen.pwdx
Befehl, der mitgeliefert wird ,procps
sodass dies möglicherweise Ihre Antwort ist.pwdx
. Aber FreeBSD nicht.getcwd(3)
verwendet, indem Siestat(".")
und anrufenreaddir("..")
, eine passende Inode-Nummer finden und den Vorgang nach oben wiederholen, bis er das Stammverzeichnis erreicht. Viel Glück dabei , dass im Rahmen eines anderen Verfahrens. (Ich nehme an, man könnte verwendenptrace
, um einen Anruf angetcwd
...)Antworten:
Ich habe eine Lösung, die verwendet
lsof
. Es ist standardmäßig nicht auf BSD installiert. Wenn jemand es auf BSD verwenden möchte, muss es installiert werden.Erstellen Sie ein Shell-Skript:
Kopieren Sie es in ein Verzeichnis in Ihrem Pfad. Es gibt das Arbeitsverzeichnis der PID aus, das im ersten Argument, IE, angegeben ist
quelle
lsof -p $PID | awk '/cwd/{print $9}'
.AWK
Experte.lsof
Overhead mit nurlsof -d cwd -a -p $1
POSIX bietet nicht viel, um Informationen über nicht verwandte Prozesse zu erhalten. Es gibt
ps
wirklich nur und es gibt keine Informationen über das aktuelle Verzeichnis. Die C-Level-APIs sind nicht besser (tatsächlich können die meisten Informationen, die von abgerufen werden,ps
nur durch Analysieren der Ausgabe abgerufen werden¹).Lustigerweise bietet POSIX eine tragbare Möglichkeit, um umgekehrt zu sein: Wenn eine Datei angegeben ist, können Sie durch Aufrufen herausfinden, welche Prozesse sie geöffnet haben
fuser
. Das folgende Snippet listet die PIDs der Prozesse auf, die ein bestimmtes Arbeitsverzeichnis haben:Wenn Sie Informationen zu Prozessen auf eine Weise erhalten möchten, die in der Praxis portabel ist, verwenden Sie lsof . Der Autor von lsof hat alle verschiedenen Methoden zum Abrufen von Informationen zu verschiedenen Unix-Varianten implementiert.
Für gelegentliches Surfen:
Für automatisiertes Parsen:
Beachten Sie, dass
lsof
Zeilenumbrüche durch die Zeichenfolge ersetzt werden\n
.Einige Unix-Varianten bieten Methoden an, für die keine Software von Drittanbietern erforderlich ist. Diese Methoden sind jedoch zwangsläufig für jede Variante spezifisch. Ein sehr verwandter Hinweis finden Sie unter Portabilität von Dateideskriptor-Links
¹ Einige alte Unices haben
ps
setuid root und lesen den Kernelspeicher. Daher war die Verwendung dieser setuid-Binärdatei der einzige Weg, um diese Informationen zu erhalten.quelle
ps -options
[= Unix-Optionen mit einem Bindestrich] oderps options
[= BSD-Stiloptionen ohne ein Strich]. Jeder kommt mit seinen eigenen Optionen (-X
undX
sind wahrscheinlich nicht die gleiche Option). Mit BSD-Optionen kann man:ps auexwww |grep [f]oo |tr ' ' '\n' |grep 'CWD='
das CWD von foo erhalten. Es funktioniert auf einem (Nicht-Gnu-Ps) Aix, auf einem (Gnu-Ps) Linux, aber es schlägt in Cygwin fehl :( Und auf Solaris müssen Sie abrechnen/usr/ucb/ps
, um die richtigen Ps zu erhalten. Also wahrscheinlich Nicht-Posix?ps
ist möglicherweise der klassische Unix-Befehl, der zwischen Unix-Varianten am stärksten voneinander abweicht . Es hat in letzter Zeit tendenziell konvergiert, aber POSIX standardisiert nur einige Optionen im SysV-Stil, und keine davon gibt das aktuelle Verzeichnis an. Ihr Befehl funktioniert nicht, meinten SiePWD=
eher alsCWD=
? Das gibt Ihnen nicht die CWD, sondern den Wert derPWD
Umgebungsvariablen (oder eine falsche Übereinstimmung aufgrund der ungefähren Analyse), was normalerweise nur dann korrekt ist, wenn das Programm sein aktuelles Verzeichnis nach dem Start von a nicht geändert hat Schale.Ich werde meine eigene Antwort beisteuern.
Eine Option im Kontext einer interaktiven Shell (die Frage konzentriert sich auf diesen Kontext) könnte darin bestehen, automatisch einen Link à la zu pflegen
/proc/$PID/cwd
, indem die von Bash bereitgestellte Automatisierungsmöglichkeit verwendet wird:Die
f
Option ist erforderlich, da der Link häufig überschrieben wird. DieT
Option ist erforderlich, da dief
Option ansonsten anscheinend ordnungsgemäß funktioniert.Muscheln können kooperativ gemacht werden, indem dies in Beispiel verwendet wird
~/.bashrc
:Eine Shell oder ein Terminal kann mit
CWD_LINK_NAME
einem beliebigen relevanten Wert ausgeführt werden. Ex.CWD_LINK_NAME="~/$SOME_ROLE_NAME" gnome-terminal
Eine weitere Alternative ist das gleiche Konzept mit der Birne verfolgen in einem variablen Arbeitsverzeichnis, das Tracking auf beide basieren @Gilles und @enedil Beiträge:
Dies ist jedoch weniger genau und weniger praktisch, obwohl es in den seltenen Fällen immer noch die einzige Möglichkeit ist, die
$PROMPT_COMMAND
nicht in der anderen Shell eingestellt werden kann.Ich bin für die erste Option (ich warte immer noch, bevor ich eine Antwort auswähle, falls jemals andere Beiträge kommen).
quelle