Выполнять команды последовательно в Python - PullRequest
19 голосов
/ 11 декабря 2008

Я хотел бы выполнить несколько команд подряд:

т.е. (просто чтобы проиллюстрировать мою потребность):

cmd (оболочка)

тогда

cd dir

и

Ls

и прочитайте результат ls.

Есть идеи с модулем подпроцесса?

UPDATE:

cd dir и ls - только пример. Мне нужно выполнить сложные команды (в определенном порядке, без какой-либо конвейерной работы). На самом деле, мне нужна одна оболочка подпроцесса и возможность запускать на ней много команд.

Ответы [ 5 ]

25 голосов
/ 11 декабря 2008

Для этого вам необходимо:

  • предоставляет аргумент shell=True в вызове subprocess.Popen и
  • разделяет команды:
    • ; при работе под * nix-оболочкой (bash, ash, sh, ksh, csh, tcsh, zsh и т. Д.)
    • & если работает под cmd.exe Windows
20 голосов
/ 11 декабря 2008

Существует простой способ выполнить последовательность команд.

Используйте следующее в subprocess.Popen

"command1; command2; command3"

Или, если вы застряли с окнами, у вас есть несколько вариантов.

  • Создайте временный файл ".BAT" и предоставьте его subprocess.Popen

  • Создать последовательность команд с разделителями "\ n" в одной длинной строке.

Используйте "" "вот так.

"""
command1
command2
command3
"""

Или, если вы должны делать что-то по частям, вы должны делать что-то вроде этого.

class Command( object ):
    def __init__( self, text ):
        self.text = text
    def execute( self ):
        self.proc= subprocess.Popen( ... self.text ... )
        self.proc.wait()

class CommandSequence( Command ):
    def __init__( self, *steps ):
        self.steps = steps
    def execute( self ):
        for s in self.steps:
            s.execute()

Это позволит вам построить последовательность команд.

3 голосов
/ 11 декабря 2008

Поиск 'bar' в каждом файле, имя которого содержит 'foo':

from subprocess import Popen, PIPE
find_process = Popen(['find', '-iname', '*foo*'], stdout=PIPE)
grep_process = Popen(['xargs', 'grep', 'bar'], stdin=find_process.stdout, stdout=PIPE)
out, err = grep_process.communicate()

'out' и 'err' являются строковыми объектами, содержащими стандартный вывод и, в конечном итоге, вывод ошибок.

2 голосов
/ 11 декабря 2008

Да, функция <a href="http://docs.python.org/library/subprocess.html" rel="nofollow noreferrer">subprocess.Popen</a>() поддерживает аргумент ключевого слова cwd, с помощью которого можно указать каталог, в котором выполняется процесс.

Я думаю, что первый шаг, оболочка, не нужен, если все, что вам нужно, это запустить ls, нет необходимости запускать его через оболочку.

Конечно, вы также можете просто передать желаемый каталог в качестве аргумента ls.

Обновление: возможно, стоит отметить, что для типичных оболочек cd реализован в самой оболочке, а не является внешней командой на диске. Это потому, что необходимо изменить текущий каталог процесса, что должно быть сделано изнутри процесса. Так как команды запускаются как дочерние процессы, порожденные оболочкой, они не могут этого сделать.

0 голосов
/ 03 октября 2015

ниже скрипта Python имеет 3 функции, которые вы пошли просто извините:

import sys
import subprocess

def cd(self,line):
    proc1 = subprocess.Popen(['cd'],stdin=subprocess.PIPE)
    proc1.communicate()

def ls(self,line):
    proc2 = subprocess.Popen(['ls','-l'],stdin=subprocess.PIPE)
    proc2.communicate()

def dir(silf,line):
    proc3 = subprocess.Popen(['cd',args],stdin=subprocess.PIPE)
    proc3.communicate(sys.argv[1])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...