Невозможно запустить команду dd через popen в python

Код:

from subprocess import PIPE, Popen
op = Popen("lsblk", shell=True, stdout=PIPE).stdout.read()
print op
a = raw_input("Enter Path of Device to be copied : ",)
b = raw_input("Enter new name for Image : ",)
print a+b
op=Popen("dd if="+a+" of="+b+" bs=512").stdout.read()
print op
op = Popen("fls "+b+"|grep "+c, shell=True, stdout=PIPE).stdout.read()
print op
ar = op.split(" ")
d = ar[1]
op = Popen("istat "+b+" "+d, shell=True, stdout=PIPE).stdout.read()
print op
e = raw_input("Enter new filename")
op = Popen("icat "+b+" "+d+" >> "+e, shell=True, stdout=PIPE).stdout.read()
print op
op = Popen("gedit "+e, shell=True, stdout=PIPE).stdout.read()
print op

Ошибка:

Traceback (most recent call last):   
  File "a3.py", line 8, in <module>
    op=Popen("dd if="+a+" of="+b+" bs=512").stdout.read()
  File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__
    errread, errwrite)
  File "/usr/lib64/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception OSError: [Errno 2] No such file or directory

Пожалуйста, помогите, я не знаком с subprocess.Popen и я новичок в программировании.

2 ответа

Решение
Popen(["command", "-opt", "value", "arg1", "arg2" ...], stdout=PIPE)

Вы не используете Popen функционировать правильно. Вот краткий пример, рассматривающий ваш скрипт:

op = Popen(["dd", "if="+a, "of="+b, "bs=512"], stdout=PIPE)

Вы должны взглянуть на документацию подпроцесса (help(subprocess) в переводчике)

Было бы лучше передать список аргументов, если вы хотите передать по конвейеру, вы можете использовать Popen, передающий stdout одного процесса на stdin другого, если вы хотите увидеть только выходные данные, используйте check_output и перенаправить stdout в файл, передав файл объекта в стандартный вывод, что-то вроде следующего:

from subprocess import check_output,check_call, Popen,PIPE

op = check_output(["lsblk"])
print op
a = raw_input("Enter Path of Device to be copied : ", )
b = raw_input("Enter new name for Image : ", )
print a + b
# get output
op = check_output(["dd", "if={}".format(a), "of={}".format(b), "bs=512"])
print op
# pass list of args without shell=True
op = Popen(["fls", b], stdout=PIPE)
# pipe output from op to grep command
op2 = Popen(["grep", c],stdin=op.stdout,stdout=PIPE)
op.stdout.close()
# get stdout from op2
d = op.communicate()[0].split()[1]

op = check_output(["istat",b, d])
print op
e = raw_input("Enter new filename")
# open the file with a to append passing file object to stdout
# same as >> from bash
with open(a, "a") as f:
    check_call(["icat", b], stdout=f)

# open file and read
with open(e) as out:
    print(out.read())

Я не уверен где c исходит от вас, поэтому вы должны убедиться, что это определено где-то, check_call а также check_output вызовет CalledProcessError для любого ненулевого состояния выхода, так что вы можете захотеть поймать его с помощью try / кроме и так далее, что будет уместно в случае возникновения ошибки.

Ваш код не выполняется при первом вызове Popen, когда вы передаете строку без shell=Trueвам нужно передать список аргументов, как в приведенном выше коде, обычно передача списка аргументов без использования shell=True будет лучшим подходом, особенно при получении ввода от пользователя.

Другие вопросы по тегам