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>

questionAnswers(3)

yourAnswerToTheQuestion