Saya percaya bahwa menjalankan perintah eksternal dengan lingkungan yang sedikit dimodifikasi adalah kasus yang sangat umum. Begitulah cara saya cenderung melakukannya:
import subprocess, os
my_env = os.environ
my_env["PATH"] = "/usr/sbin:/sbin:" + my_env["PATH"]
subprocess.Popen(my_command, env=my_env)
Saya punya firasat bahwa ada cara yang lebih baik; apakah ini terlihat baik-baik saja?
python
subprocess
popen
Oren_H
sumber
sumber
os.pathsep
daripada ":" untuk jalur yang berfungsi lintas platform. Lihat stackoverflow.com/questions/1499019/…/usr/sbin
:-)Jawaban:
Saya pikir
os.environ.copy()
lebih baik jika Anda tidak bermaksud memodifikasi os.environ untuk proses saat ini:sumber
os.environ.copy
keenv
variabel tetapi Anda perlu untuk menetapkan hasil memanggil metodeos.environ.copy()
untukenv
.shell=True
dalamsubprocess.Popen
permohonan Anda . Perhatikan bahwa ada implikasi keamanan yang berpotensi terjadi.my_command
hanya perintah untuk dijalankan. Ini bisa berupa misalnya/path/to/your/own/program
atau pernyataan "dieksekusi" lainnya.Itu tergantung pada apa masalahnya. Jika ingin mengkloning dan memodifikasi lingkungan, salah satu solusinya adalah:
Tapi itu agak tergantung pada variabel yang diganti adalah pengidentifikasi python yang valid, yang paling sering adalah (seberapa sering Anda mengalami nama variabel lingkungan yang bukan garis bawah + alfanumerik atau variabel yang dimulai dengan angka?).
Kalau tidak, Anda bisa menulis sesuatu seperti:
Dalam kasus yang sangat aneh (seberapa sering Anda menggunakan kode kontrol atau karakter non-ascii dalam nama variabel lingkungan?) Bahwa kunci-kunci lingkungan
bytes
Anda tidak dapat (pada python3) bahkan menggunakan konstruksi itu.Seperti yang Anda lihat teknik (terutama yang pertama) yang digunakan di sini manfaat pada kunci lingkungan biasanya adalah pengidentifikasi python yang valid, dan juga dikenal sebelumnya (pada waktu pengkodean), pendekatan kedua memiliki masalah. Dalam kasus di mana bukan itu masalahnya Anda mungkin harus mencari pendekatan lain .
sumber
dict(mapping, **kwargs)
. Saya pikir itu atau. Catatan: ini disalinos.environ
tanpa memodifikasinya seperti yang disarankan oleh @Daniel Burke dalam jawaban yang saat ini diterima tetapi jawaban Anda lebih ringkas. Di Python 3.5+ Anda bahkan bisa melakukannyadict(**{'x': 1}, y=2, **{'z': 3})
. Lihat pep 448 .Anda dapat menggunakannya
my_env.get("PATH", '')
sebagai penggantimy_env["PATH"]
jika dalam kasusPATH
entah bagaimana tidak didefinisikan di lingkungan asli, tetapi selain itu terlihat baik-baik saja.sumber
Dengan Python 3.5 Anda bisa melakukannya dengan cara ini:
Di sini kita berakhir dengan salinan
os.environ
danPATH
nilai yang diganti .Itu dimungkinkan oleh PEP 448 (Generalisasi Pembongkaran Tambahan).
Contoh lain. Jika Anda memiliki lingkungan default (yaitu
os.environ
), dan dikt Anda ingin mengganti default dengan, Anda dapat mengekspresikannya seperti ini:sumber
Untuk sementara mengatur variabel lingkungan tanpa harus menyalin objek os.envrion dll, saya melakukan ini:
sumber
Parameter env menerima kamus. Anda cukup mengambil os.environ, menambahkan kunci (variabel yang Anda inginkan) (ke salinan dikt jika Anda harus) untuk itu dan menggunakannya sebagai parameter untuk
Popen
.sumber
os.environ['SOMEVAR'] = 'SOMEVAL'
Saya tahu ini telah dijawab untuk beberapa waktu, tetapi ada beberapa poin yang beberapa mungkin ingin tahu tentang menggunakan PYTHONPATH daripada PATH dalam variabel lingkungan mereka. Saya telah menjabarkan penjelasan tentang menjalankan skrip python dengan cronjobs yang berhubungan dengan lingkungan yang dimodifikasi dengan cara yang berbeda ( ditemukan di sini ). Kupikir itu akan bermanfaat bagi mereka yang, seperti aku, membutuhkan sedikit lebih banyak daripada jawaban yang diberikan.
sumber
Dalam keadaan tertentu Anda mungkin hanya ingin mewariskan variabel lingkungan yang dibutuhkan subproses Anda, tetapi saya pikir Anda memiliki ide yang tepat secara umum (itulah cara saya melakukannya juga).
sumber