Dalam Python, apakah ada cara portabel dan sederhana untuk menguji apakah ada program yang dapat dieksekusi?
Secara sederhana saya maksudkan sesuatu seperti which
perintah yang akan sempurna. Saya tidak ingin mencari PATH secara manual atau sesuatu yang melibatkan mencoba untuk mengeksekusinya dengan Popen
& al dan melihat apakah itu gagal (itulah yang saya lakukan sekarang, tetapi bayangkan itu launchmissiles
)
which
, modul pihak ketiga: code.activestate.com/pypm/whichJawaban:
Cara termudah yang bisa saya pikirkan:
Sunting : Sampel kode yang diperbarui untuk memasukkan logika untuk menangani kasus di mana argumen yang disediakan sudah path lengkap ke executable, yaitu "yang / bin / ls". Ini meniru perilaku perintah 'yang' UNIX.
Sunting : Diperbarui untuk menggunakan os.path.isfile () alih-alih os.path.exists () per komentar.
Sunting :
path.strip('"')
sepertinya hal yang salah untuk dilakukan di sini. Baik Windows maupun POSIX tidak muncul untuk mendorong item PATH yang dikutip.sumber
PATHEXT
var env karenacommand
adalah sebagai berlaku sebagaicommand.com
sepertiscript
vsscript.bat
Saya tahu ini adalah pertanyaan kuno, tetapi Anda dapat menggunakannya
distutils.spawn.find_executable
. Ini telah didokumentasikan sejak python 2.4 dan telah ada sejak python 1.6.Juga, Python 3.3 sekarang menawarkan
shutil.which()
.sumber
win32
,distutils.spawn.find_executable
implementasi hanya mencari.exe
daripada menggunakan daftar ekstensi untuk mencari yang ditetapkan%PATHEXT%
. Itu tidak bagus, tetapi mungkin berhasil untuk semua kasus yang dibutuhkan seseorang.from distutils import spawn
php_path = spawn.find_executable("php")
distutils.spawn
tidak tersedia andal: dengan Sistem saya menginstal (/ usr / bin / python) dari Python 2.7.6 pada OS X 10.10, saya mendapatkanAttributeError: 'module' object has no attribute 'spawn'
:, meskipun anehnya itu bekerja pada mesin yang sama dengan versi Python yang sama, tetapi dari instalasi virtualenv.import distutils.spawn
, atau ikutifrom distutils import spawn
sintaks daripada hanyaimport distutils
. Kalau tidak, itu mungkin tidak dapat diakses dan Anda akan mendapatkan di atasAttributeError
bahkan jika itu ada.Python 3.3 sekarang menawarkan shutil.which () .
sumber
Untuk python 3.2 dan sebelumnya:
Ini adalah satu-baris Jawaban Jay , Juga di sini sebagai fungsi lambda:
Atau terakhir, indentasi sebagai fungsi:
Untuk python 3.3 dan yang lebih baru:
Sebagai pelaut Jan-Philip Gehrcke Jawaban :
Sebagai def:
sumber
x
yang seharusnyacmd
os.path.join(path, cmd)
file, bukan? Lagipula, direktori juga dapat memiliki set bit yang dapat dieksekusi ...mkdir -p -- "$HOME"/bin/dummy && PATH="$PATH":"$HOME"/bin && python -c 'import os; print any(os.access(os.path.join(path, "dummy"), os.X_OK) for path in os.environ["PATH"].split(os.pathsep))' && rmdir -- "$HOME"/bin/dummy
and os.path.isfile(...)
ke tempat yang sesuai sudah cukup untuk memperbaikinyaHanya ingat untuk menentukan ekstensi file di windows. Kalau tidak, Anda harus menulis banyak rumit
is_exe
untuk windows menggunakanPATHEXT
variabel lingkungan. Anda mungkin hanya ingin menggunakan FindPath .OTOH, mengapa Anda repot-repot mencari yang dapat dieksekusi? Sistem operasi akan melakukannya untuk Anda sebagai bagian dari
popen
panggilan & akan memunculkan pengecualian jika executable tidak ditemukan. Yang perlu Anda lakukan adalah menangkap pengecualian yang benar untuk OS yang diberikan. Perhatikan bahwa pada Windows,subprocess.Popen(exe, shell=True)
akan gagal secara diam-diam jikaexe
tidak ditemukan.Menggabungkan
PATHEXT
ke dalam implementasi di ataswhich
(dalam jawaban Jay):sumber
yield
dalamext_candidates
, memberi saya pemahaman yang lebih baik tentang cara kerja kata kunci ituUntuk platform * nix (Linux dan OS X)
Ini sepertinya bekerja untuk saya:
Diedit untuk bekerja di Linux, terima kasih kepada Mestreion
Apa yang kami lakukan di sini adalah menggunakan perintah builtin
type
dan memeriksa kode keluar. Jika tidak ada perintah seperti itu,type
akan keluar dengan 1 (atau kode status bukan nol).Bit tentang stdout dan stderr hanya untuk membungkam output dari
type
perintah, karena kami hanya tertarik pada kode status keluar.Contoh penggunaan:
sumber
type
shell builtin, bukan file yang dapat dieksekusi, jadisubprocess.call()
gagal di sini.OSError: [Errno 2] No such file or directory
. Mungkin di Mactype
adalah perintah sebenarnyashell=True
dan ganti["type", cmd]
untuk"type " + cmd
Lihat modul os.path untuk mengetahui beberapa fungsi berguna pada nama path. Untuk memeriksa apakah file yang ada dapat dieksekusi, gunakan os.access (path, mode) , dengan mode os.X_OK.
EDIT:
which()
Implementasi yang disarankan tidak memiliki satu petunjuk - gunakanos.path.join()
untuk membangun nama file lengkap.sumber
Atas dasar itu lebih mudah untuk meminta maaf daripada izin saya hanya akan mencoba menggunakannya dan menangkap kesalahan (OSError dalam hal ini - saya memeriksa file tidak ada dan file tidak dapat dieksekusi dan mereka berdua memberikan OSError).
Ini membantu jika executable memiliki sesuatu seperti
--version
flag yang merupakan no-op cepat.Ini bukan solusi umum, tetapi akan menjadi cara termudah untuk banyak kasus penggunaan - kasus di mana kode perlu mencari satu executable terkenal.
sumber
--version
program bernamalaunchmissiles
!launchmissies
ada kecuali Anda ingin meluncurkan rudal? Lebih baik untuk mengeksekusinya dan bertindak berdasarkan status keluar / pengecualiangit
bahwa Anda mungkin tidak ingin menjalankan secara membabi buta.Saya tahu bahwa saya menjadi sedikit ahli nujum di sini, tetapi saya menemukan pertanyaan ini dan solusi yang diterima tidak bekerja untuk saya untuk semua kasus. Secara khusus, deteksi mode "executable", dan persyaratan untuk memasok ekstensi file. Lebih jauh lagi, baik python3.3's
shutil.which
(usesPATHEXT
) dan python2.4 +distutils.spawn.find_executable
(hanya mencoba menambahkan'.exe'
) hanya berfungsi dalam subset kasus.Jadi saya menulis versi "super" (berdasarkan jawaban yang diterima, dan
PATHEXT
saran dari Suraj). Versiwhich
tugas ini sedikit lebih teliti, dan mencoba serangkaian teknik "luas-lebar" pertama, dan akhirnya mencoba pencarian yang lebih baik atasPATH
ruang:Penggunaannya terlihat seperti ini:
Solusi yang diterima tidak bekerja untuk saya dalam kasus ini, karena ada file seperti
meld.1
,meld.ico
,meld.doap
, dll juga di direktori, salah satunya dikembalikan bukan (mungkin karena leksikografi pertama) karena tes dieksekusi dalam jawaban yang diterima tidak lengkap dan memberikan positif palsu.sumber
Contoh terbaik adalah modul python bulit-in shutil.which () dengan Python 3. Tautannya adalah https://hg.python.org/cpython/file/default/Lib/shutil.py
sumber
Saya menemukan sesuatu di StackOverflow yang memecahkan masalah bagi saya. Ini berfungsi asalkan executable memiliki opsi (seperti --help atau --version) yang menampilkan sesuatu dan mengembalikan status keluar nol. Lihat Menekan keluaran dalam panggilan Python ke executable - "hasil" di akhir cuplikan kode dalam jawaban ini akan menjadi nol jika dieksekusi di jalur, kalau tidak kemungkinan besar adalah 1.
sumber
Ini tampaknya cukup sederhana dan berfungsi baik di python 2 dan 3
sumber
command -v executable
atautype executable
untuk menjadi universal. Ada kasus di mana pada Mac tidak mengembalikan hasil yang diharapkan.Sebuah pertanyaan penting adalah " Mengapa Anda perlu menguji apakah executable ada?" Mungkin tidak? ;-)
Baru-baru ini saya membutuhkan fungsi ini untuk meluncurkan viewer untuk file PNG. Saya ingin mengulangi beberapa pemirsa yang telah ditentukan dan menjalankan yang pertama yang ada. Untungnya, saya menemukan
os.startfile
. Jauh lebih baik! Sederhana, portabel dan menggunakan penampil default pada sistem:Pembaruan: Saya salah tentang
os.startfile
menjadi portabel ... Ini hanya Windows. Di Mac Anda harus menjalankanopen
perintah. Danxdg_open
di Unix. Ada masalah Python tentang menambahkan dukungan Mac dan Unix untukos.startfile
.sumber
Anda dapat mencoba lib eksternal yang disebut "sh" ( http://amoffat.github.io/sh/ ).
sumber
Dukungan windows ditambahkan
sumber
Anda dapat mengetahui apakah ada file dengan modul os. executable pada khususnya tampaknya cukup tidak dapat dipercaya mengingat banyak hal yang dapat dieksekusi pada nix yang tidak ada di windows dan sebaliknya.
sumber
Tampaknya pilihan yang jelas adalah "yang", mem-parsing hasil melalui popen, tetapi Anda bisa mensimulasikannya menggunakan kelas os. Dalam pseudopython, akan terlihat seperti ini:
sumber
which
perintah; ada versi UnxUtils, tetapi Anda harus tahu / tentukan ekstensi, jika tidak program tidak akan ditemukan.Jadi pada dasarnya Anda ingin menemukan file dalam sistem file yang terpasang (tidak harus hanya di direktori PATH saja) dan periksa apakah itu dapat dieksekusi. Ini berarti rencana berikut:
Menurut saya, melakukan ini dengan cara yang portabel akan membutuhkan banyak daya komputasi dan waktu. Benarkah itu yang Anda butuhkan?
sumber
Ada skrip which.py dalam distribusi Python standar (misalnya pada Windows
'\PythonXX\Tools\Scripts\which.py'
).EDIT:
which.py
tergantung padals
karena itu bukan cross-platform.sumber
Tidak ada contoh sebelumnya yang berfungsi pada semua platform. Biasanya mereka gagal bekerja di Windows karena Anda dapat mengeksekusi tanpa ekstensi file dan Anda dapat mendaftarkan ekstensi baru. Sebagai contoh pada Windows jika python terinstal dengan baik, itu cukup untuk menjalankan 'file.py' dan itu akan bekerja
Satu-satunya solusi yang valid dan portabel yang saya miliki adalah menjalankan perintah dan melihat kode kesalahan. Setiap executable yang layak harus memiliki seperangkat parameter panggilan yang tidak akan melakukan apa pun.
sumber
Menggunakan pustaka kain python:
sumber
which(1)
yang tidak ada pada semua sistem.