Você não está realmente executando um comando bash
. O que você está fazendo é executar um executável diretamente e passar argumentos.
Tente o seguinte script para ver o que está acontecendo:
import subprocess
p = subprocess.Popen(["echo", "a", "b", "|", "rev"], stdout=subprocess.PIPE)
print p.communicate()
A saída será:
('a b | rev\n', None)
Não há redirecionamento acontecendo, o "|" está sendo passado literalmente. Ou seja, é como se você tivesse digitado find ... \| parallel ...
. Assim, o erro.
Existem duas maneiras de corrigir isso.
-
O caminho mais fácil: passe
shell=True
parasubprocess.Popen
. Isso será executado através da casca, com tudo o que isso implica. Se você fizer isso, você também precisará passar uma string em vez de um array:import subprocess p = subprocess.Popen("echo a b | rev", stdout=subprocess.PIPE, shell=True) print p.communicate() # Result: ('b a\n', None)
Se você fizer isso, tenha muito cuidado com a substituição de argumentos em sua string .
-
A maneira robusta: abra dois processos usando o Python e conecte-os juntos.
import subprocess # First command p1 = subprocess.Popen(["echo", "a", "b"], stdout=subprocess.PIPE) # Second command's input linked to the first one's output p2 = subprocess.Popen(["rev"], stdin=p1.stdout, stdout=subprocess.PIPE) # Read from p2 to get the output print p2.communicate() # Result: ('b a\n', None)
Isso é mais robusto e não gera uma casca extra, mas, por outro lado, é mais digitação. Se você fizer isso, observe que nenhuma substituição de shell acontece . No seu caso, não parece que você precisa, mas se você quiser usar, por exemplo,
~
, você terá que fazer isso através do Python (por exemplo,os.getenv("HOME")
).