Melewati argumen ke subprocess.call

Saya menghadapi situasi yang tidak menyenangkan dengan instalasi diam-diam dari beberapa program. Saya tidak yakin mereka menggunakan konvensi apa pun untuk tanda instalasi dengan nilai tetapi di sini apa yang harus digunakan untuk instalasi:

"path with spaces\setup.exe" -uninst -s -f2"path with spaces\uninstall.log"

Anda tidak dapat menggunakan --f2="path with spasi\uninstall.log" atau -f2="path with spasi\uninstall.log" atau -f2 "path dengan spasi\uninstall.log"

jadi jika saya menggunakan Python berikut:

command = [self.setup_exe, '-uninst', '-s', fr'-f2"{uninstall_log_file}"']

perintah yang dijalankan subproses (dapatkan dari subprocess.list2cmdline(command)) adalah:

setup.exe" -uninst -s -f2\"some path\temp build 12\uninstall.log\"

pada dasarnya muncul garis miring dan instalasi gagal. Secara teoritis saya dapat membuat string sendiri tetapi penyedia yang sama untuk executable lain menyediakan sintaks lain yang lebih kompatibel dengan subproses. Saya bertanya-tanya apakah mungkin menyiapkan daftar argumen untuk memenuhi persyaratan penginstal?


person Beliaev Maksim    schedule 19.06.2020    source sumber
comment
Bagaimana Anda sebenarnya memanggil perintah itu? Sepertinya Anda mungkin menggunakan shell=True padahal seharusnya tidak.   -  person chepner    schedule 19.06.2020
comment
@chepner, Anda benar, saya menggunakan shell=True. Sejauh yang saya pahami, ini diperlukan jika saya perlu menjalankan perintah sebagai pengguna yang ditinggikan (misalnya dengan PowerShell). Atau akankah itu berhasil?   -  person Beliaev Maksim    schedule 19.06.2020
comment
Tidak, menggunakan shell=True hanya beralih dari menjalankan perintah secara langsung ke menjalankan shell dengan argumen yang dibangun agar shell menjalankan perintah untuk Anda.   -  person chepner    schedule 19.06.2020
comment
inilah cara saya menelepon sekarang: subprocess.call(command)   -  person Beliaev Maksim    schedule 19.06.2020
comment
@chepner, sekarang ia membuat lapisan tanda kutip lain: -f2\some path\uninstall.log\   -  person Beliaev Maksim    schedule 19.06.2020
comment
Anda menyertakan tanda kutip dalam definisi Anda tentang command: fr'-f2"{uinstall_log_file}"'. Anda dapat menghilangkannya.   -  person chepner    schedule 19.06.2020
comment
@chepner, sayangnya tidak, maka ia memperlakukan seluruh argumen seperti spasi dan membuat -f2path..... Tidak berfungsi :(   -  person Beliaev Maksim    schedule 20.06.2020
comment
Berapa nilai sebenarnya dari uninstall_log_file, dan apa perintah sebenarnya yang Anda gunakan untuk menjalankan file yang dapat dieksekusi?   -  person chepner    schedule 20.06.2020
comment
@chepner, lihat perintah pertama di pertanyaan. Pada dasarnya itu mungkin jalur apa pun yang mengandung ruang. Jalur diminta dari pengguna. Misalnya C:\Uji 1 2 3 4\log.log   -  person Beliaev Maksim    schedule 20.06.2020
comment
Begitulah cara Anda memintanya dari baris perintah shell. Apa kode Python sebenarnya yang Anda gunakan untuk menjalankan perintah?   -  person chepner    schedule 20.06.2020
comment
Saya pikir saya menjawab. subproses.panggilan(perintah). Saya mencoba shell dan non shell   -  person Beliaev Maksim    schedule 22.06.2020
comment
Maka masalahnya adalah definisi Anda tentang command, seperti yang saya tunjukkan sebelumnya. Anda menambahkan tanda kutip yang dimaksudkan untuk mencegah shell memproses nilai uninstall_log_file, namun apakah tidak ada shell seperti itu. Coba command = [..., '-f2', uninstall_log_file].   -  person chepner    schedule 22.06.2020
comment
Saya siap menyerah dengan sintaks yang digunakan untuk diam ini. Lebih mudah untuk membuat string sendiri. Saya rasa itu tidak mungkin dilakukan melalui daftar   -  person Beliaev Maksim    schedule 22.06.2020
comment
@chepner, tidak, saya tidak bisa menggunakannya. Tidak mungkin ada spasi antara -f2 dan path   -  person Beliaev Maksim    schedule 22.06.2020
comment
Seperti dalam pertanyaan: Anda tidak dapat menggunakan --f2=path dengan spasi\uninstall.log atau -f2=path dengan spasi\uninstall.log atau -f2 path dengan spasi\uninstall.log   -  person Beliaev Maksim    schedule 22.06.2020


Jawaban (1)


Jika kamu lari

"path with spaces\setup.exe" -uninst -s -f2"path with spaces\uninstall.log"

dari baris perintah, panggilan yang setara ke subprocess.call adalah

uninstall_log_file = r"path with spaces\uninstall.log"
command = [self.setup_exe, '-uninst', '-s', f'-f2{uninstall_log_file}']
subprocess.call(command)
person chepner    schedule 21.06.2020
comment
sayangnya ini tidak berhasil, saya sudah mencobanya. Jika saya meletakkan jalur tanpa spasi, itu akan berhasil. Jika saya meletakkan jalur dengan spasi maka tidak karena argumen akan terlihat seperti -f2path dengan spasi/log.log. Jadi ini tidak berhasil - person Beliaev Maksim; 22.06.2020
comment
Saya juga mencoba yang ini: stackoverflow.com/questions/43022687/ namun saya berasumsi ada perbedaan pada penyedia. Karena di sana argumennya akan terlihat seperti -f2=path dengan spasi. Dalam contoh saya dari CMD, tanda sama dengan tidak diperbolehkan - person Beliaev Maksim; 22.06.2020
comment
Saya membuat sedikit penyesuaian pada jawabannya, menjadikan uninstall_log_file string mentah daripada f-string yang menginterpolasi nilainya. Saya tidak yakin apakah itu akan membuat perbedaan. - person chepner; 22.06.2020
comment
baru saja melakukan tes. Sayangnya tidak ada. Saya menjalankan subproses dengan daftar tetapi untuk pemeriksaan juga menjalankan list2cmdline. Itu menambahkan tanda kutip di sekitar -f2 -› -f2path. Jadi instalasi gagal. yang berfungsi tapi aneh adalah: command = [f'{self.setup_exe}', '-uninst', '-s', fr'-f2{uninstall_log_file}'] command = .join(command) lalu panggil subproses dengan Sebuah benang. Apakah menurut Anda mungkin untuk mendapatkan daftar penggunaan yang sama? - person Beliaev Maksim; 23.06.2020