użycie podprocesowych symboli wieloznacznych

import os

import subprocess

proc = subprocess.Popen(['ls','*.bc'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

out,err = proc.communicate()

print out

Ten skrypt powinien wydrukować wszystkie pliki z .przyrostek bc zwraca jednak pustą listę. Jeśli zrobię ls *.BC ręcznie w wierszu poleceń działa. Robi ['ls', ' test.bc'] wewnątrz skryptu działa również, ale z jakiegoś powodu symbol gwiazdy nie działa.. Jakieś pomysły ?

Author: martineau, 2012-04-03

3 answers

Musisz DOSTARCZYĆ shell=True Aby wykonać polecenie za pomocą interpretera powłoki. Jeśli jednak to zrobisz, nie będziesz mógł już podawać listy jako pierwszego argumentu, ponieważ argumenty zostaną wtedy zacytowane. Zamiast tego określ surową linię poleceń, tak jak chcesz, aby została przekazana do powłoki:

 proc = subprocess.Popen('ls *.bc', shell=True,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
 83
Author: Niklas B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-03 16:01:08

Rozszerzenie Globu * jest częścią powłoki, ale domyślnie subprocessnie wysyła poleceń przez powłokę, więc polecenie (pierwszy argument, ls) jest wykonywane, a następnie literał* jest używany jako argument.

Jest to dobra rzecz, patrz blok ostrzegawczy w sekcji "Często używane argumenty" podprocesowych dokumentów. Omawia głównie implikacje bezpieczeństwa, ale może również pomóc uniknąć głupich błędów programistycznych (ponieważ nie ma magicznych znaków powłoki do worry about)

Moja główna skarga z shell=True jest to zazwyczaj sugeruje, że jest lepszy sposób na rozwiązanie problemu - w twoim przykładzie powinieneś użyć glob moduł :

import glob
files = glob.glob("*.bc")
print files # ['file1.bc', 'file2.bc']
Proces ten będzie szybszy (bez uruchamiania procesu), bardziej niezawodny i wieloplatformowy (nie zależny od platformy posiadającej polecenie ls)
 65
Author: dbr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-28 01:05:24

Oprócz wykonywania shell=True, upewnij się również, że Twoja ścieżka nie jest cytowana. W przeciwnym razie nie zostanie rozszerzony przez powłokę.

Jeśli na twojej ścieżce mogą znajdować się znaki specjalne, będziesz musiał uciec od nich ręcznie.

 0
Author: Tamaki Sakura,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-18 19:49:32