Common Lisp: Uruchamia podproces z innym katalogiem roboczym niż proces Lizp
Przypuśćmy, że mam katalog A i podkatalog B. Mam cd w A i uruchamiam seplenienie. W tym procesie lizpowania chciałbym uruchomić podproces Pythona, w którym Python widzi B jako bieżący katalog roboczy. Proces lisp musi mieć cwd w A, a proces python powinien mieć cwd w B. Jak mam to zrobić w prosty, wieloplatformowy sposób?
Szukam rozwiązania, które działa z CCL i SBCL (prawdopodobnie przy użyciu funkcji „uruchom program”) i działa dla Windows, Linux i OS X.
Przejrzałem dokumentację programu uruchomieniowego CCL i nie widziałem sposobu na zmianę cwd uruchomionego procesu.
Przejrzałem argumenty wiersza polecenia Pythona i nie widziałem takiego, który zmieniłby cwd procesu Pythona.
Myślałem o wywołaniu programu uruchomieniowego dla 'cd B; python ... ”, ale nie jestem pewien, jak to działa, ponieważ tak naprawdę uruchamia dwa programy; cd, a następnie python.
Kod Pythona jest dostarczany jako dane wejściowe (jako plik), więc nie mogę zmienić żadnego z tych kodów (dodając wywołanie os.chdir () lub podobne).
Plik opakowujący Pythona, który uruchamia plik wejściowy Pythona jako podproces, nie jest idealny, ponieważ wysyłam stdin i słucham stdout procesu python uruchomionego przez lizp. Dodanie kolejnego podprocesu między seplenieniem a procesem python, który omija plik wejściowy, oznacza, że muszę wykonać dużo przekazywania stout / stdin, i mam wrażenie, że byłoby to kruche.
Podejście krzysz00 działało bardzo dobrze. Ponieważ zmiana katalogu jest obsługiwana w seplenieniu, przed uruchomieniem procesu Pythona to podejście będzie działać w przypadku uruchamiania innych procesów w różnych podkatalogach (nie tylko python).
Dla dokumentacji, oto mój kod wykorzystujący podejście krzsz00, które działało dla SBCL i CCL. Zauważ, że używa defmacro Hoyte'a! makro zLet Over Lambda, aby łatwo uniknąć niepożądanego przechwytywania zmiennych:
<code>#+: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)))) </code>
Stosowanie:
<code>(with-cwd "./B" (run-program ...)) </code>