Uważam, że uruchamianie zewnętrznego polecenia w nieco zmodyfikowanym środowisku jest bardzo częstym przypadkiem. Tak zazwyczaj to robię:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
Mam przeczucie, że jest lepszy sposób; czy to wygląda dobrze?
python
subprocess
popen
Oren_H
źródło
źródło
os.pathsep
zamiast „:” dla ścieżek, które działają na różnych platformach. Zobacz stackoverflow.com/questions/1499019/…/usr/sbin
:-)Odpowiedzi:
Myślę, że
os.environ.copy()
lepiej, jeśli nie zamierzasz modyfikować os.environ dla bieżącego procesu:źródło
os.environ.copy
doenv
zmiennej, ale musisz przypisać wynik wywołania metodyos.environ.copy()
doenv
.shell=True
wsubprocess.Popen
wywołaniu. Pamiętaj, że może to mieć wpływ na bezpieczeństwo.my_command
to po prostu polecenie do uruchomienia. Może to być na przykład/path/to/your/own/program
dowolna inna instrukcja „wykonywalna”.To zależy od problemu. Aby sklonować i zmodyfikować środowisko, jednym rozwiązaniem może być:
Ale to w pewnym stopniu zależy od tego, czy zmienione zmienne są poprawnymi identyfikatorami python, którymi najczęściej są (jak często natrafiasz na nazwy zmiennych środowiskowych, które nie są alfanumeryczne + podkreślenie lub zmienne rozpoczynające się od liczby?).
W przeciwnym razie możesz napisać coś takiego:
W bardzo dziwnym przypadku (jak często używasz kodów sterujących lub znaków innych niż ascii w nazwach zmiennych środowiskowych?), Że klucze środowiska
bytes
nie mogą (na python3) nawet używać tej konstrukcji.Jak widać techniki (szczególnie pierwsze) zastosowane tutaj korzyści na kluczach środowiska są zwykle poprawnymi identyfikatorami python, a także znanymi z góry (w czasie kodowania), drugie podejście ma problemy. W przypadkach, w których tak nie jest, prawdopodobnie powinieneś poszukać innego podejścia .
źródło
dict(mapping, **kwargs)
. Myślałem, że to albo. Uwaga: kopiuje sięos.environ
bez modyfikacji, jak sugerował @Daniel Burke w aktualnie akceptowanej odpowiedzi, ale twoja odpowiedź jest bardziej zwięzła. W Python 3.5+ możesz to zrobićdict(**{'x': 1}, y=2, **{'z': 3})
. Zobacz pep 448 .możesz użyć
my_env.get("PATH", '')
zamiast,my_env["PATH"]
jeśli wPATH
jakiś sposób nie jest zdefiniowany w oryginalnym środowisku, ale poza tym wygląda dobrze.źródło
Z Python 3.5 możesz to zrobić w ten sposób:
W tym przypadku otrzymujemy kopię
os.environ
i przesłoniętąPATH
wartość.Było to możliwe dzięki PEP 448 (dodatkowe uogólnienia dotyczące rozpakowywania).
Inny przykład. Jeśli masz domyślne środowisko (tj.
os.environ
) I słownik, który chcesz zastąpić domyślnymi, możesz to wyrazić w następujący sposób:źródło
Aby tymczasowo ustawić zmienną środowiskową bez konieczności kopiowania obiektu os.envrion itp., Robię to:
źródło
Parametr env akceptuje słownik. Możesz po prostu wziąć os.environ, dodać klucz (pożądaną zmienną) (do kopii nagrania, jeśli musisz) i użyć go jako parametru
Popen
.źródło
os.environ['SOMEVAR'] = 'SOMEVAL'
Wiem, że odpowiedziano na to od pewnego czasu, ale są pewne kwestie, o których niektórzy mogą chcieć wiedzieć o używaniu PYTHONPATH zamiast PATH w zmiennej środowiskowej. Przedstawiłem wyjaśnienie dotyczące uruchamiania skryptów python z cronjobs, które dotyczą zmodyfikowanego środowiska w inny sposób ( tutaj ). Pomyślałem, że przydałoby się to tym, którzy tak jak ja potrzebowali nieco więcej niż ta odpowiedź.
źródło
W niektórych okolicznościach możesz chcieć przekazać tylko te zmienne środowiskowe, których potrzebuje Twój podproces, ale myślę, że ogólnie masz dobry pomysł (tak też robię).
źródło