Angenommen, ich habe ein Verzeichnis A und Unterverzeichnis B. Ich cd in A und starten Lisp. In diesem Lisp-Prozess möchte ich einen Python-Subprozess starten, in dem Python B als sein aktuelles Arbeitsverzeichnis sieht. Der Lisp-Prozess muss in A cwd haben, und der Python-Prozess sollte cwd in B haben. Wie mache ich das auf plattformübergreifende, einfache Weise?Common Lisp: Starten Sie Subprozess mit anderen Arbeitsverzeichnis als Lisp Prozess
Ich bin für eine Lösung, die mit CCL und SBCL arbeitet (wahrscheinlich mit ‚run-Programm-Funktion), und arbeitet für Windows, Linux und OS X.
schaute ich auf dem CCL-Laufprogramm Dokumentation, und ich sah keine Möglichkeit, die cwd des gestarteten Prozesses zu ändern.
Ich sah Python-Befehlszeilenargumente, und ich sah keine, die die cwd des Python-Prozesses ändern würde.
Ich dachte über einen Programmaufruf für 'CD B; Python ... ', aber ich bin nicht sicher, wie das funktionieren würde, da es wirklich zwei Programme ausführt; CD und dann Python.
Der Python-Code wird als Eingabe bereitgestellt (als Datei), daher kann ich diesen Code nicht ändern (indem ich einen Aufruf von os.chdir() oder ähnliches hinzufüge).
Eine Python-Wrapper-Datei, die die Python-Eingabedatei als Subprozess startet, ist nicht ideal, weil ich stdin sende und den stdout des python-Prozesses abhöre, der von lisp gestartet wird. Das Hinzufügen eines anderen Unterprozesses zwischen lisp und dem Python-Prozess, der die Eingabedatei verfälscht, bedeutet, dass ich eine Menge Stout/Stdin-Relaying durchführen müsste, und ich habe das Gefühl, dass dies spröde wäre.
Krzysz00 Ansatz arbeitete sehr gut. Da die Verzeichnisänderung in Lisp behandelt wird, bevor der Python-Prozess gestartet wird, funktioniert dieser Ansatz zum Starten anderer Prozesse in verschiedenen Unterverzeichnissen (nicht nur Python).
Für die Dokumentation, hier ist mein Code mit krzsz00 Ansatz, der für SBCL & CCL funktioniert. Beachten Sie, dass es Hoyte Defmacro verwendet! Makro, von Let Over Lambda, vermeiden leicht unerwünschten Variable Capture:
#+:SBCL
(defun cwd (dir)
(sb-posix:chdir dir))
(defun getcwd()
#+SBCL (sb-unix:posix-getcwd)
#+CCL (current-directory))
(defmacro! with-cwd (dir &body body)
`(let ((,g!cwd (getcwd)))
(unwind-protect (progn
(cwd ,dir)
,@body)
(cwd ,g!cwd))))
Verbrauch:
(with-cwd "./B"
(run-program ...))
Nette Vorschläge; Vielen Dank; Ich habe den externen Programmkompatibilitäts-Layer b/c nicht benutzt. Ich brauche ihn nur für sbcl und ccl, das Run-Programm für diese ist im Grunde identisch, und ich kann nicht einfach Pakete für diesen Code laden, b/c ist es Server-Seite nicht verwendet. –
Gibt es hier irgendwelche Auswirkungen auf Multithread-Programme oder wird 'cwd' pro Thread geändert? – Inaimathi
Ich denke 'cwd' ist per-Thread von meinem schnellen Skim von' thread_safety (5) ', aber ich bin mir nicht ganz sicher. Sehen Sie, ob es funktioniert. – krzysz00