-1

Code:

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

Error:

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

Please help, I am not familiar with subprocess.Popen and am a novice in programming.

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
rishabh
  • 71
  • 11
  • Running `dd` using arbitrary user input to supply the input & output file names is risky. At the very least, you should print the args and get the user to confirm that the source & destination are _really_ what they want. Also, using a blocksize of 512 bytes is rather slow. Try 64k; larger sizes may be slightly faster, depending on your hardware. – PM 2Ring Jul 20 '15 at 12:36

2 Answers2

1

You would be better passing a list of args, if you want to pipe you can use Popen piping the stdout of one process to the stdin of another, if you want to see just the output use check_output and to redirect stdout to a file pass a file object to stdout, something like the following:

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())

I am not sure where c is coming from so you need to make sure that is defined somewhere, check_call and check_output will raise a CalledProcessError for any non-zero exit status so you may want to catch that with a try/except and so whatever is appropriate if an error occurs.

Your code fails on the very first Popen call as you are passing a string without shell=True, you need to pass a list of args as in the code above, generally passing a list of args without using shell=True would be a better approach especially when taking input from a user.

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • See the 1st answer it explains it properly – rishabh Jul 20 '15 at 12:19
  • 1
    @user3430238, explains what properly? I am showing you how to avoid shell=True and actually write the code properly. Taking input from a user and using shell=True is a terrible idea, why are you calling gedit when you can read the file with python? – Padraic Cunningham Jul 20 '15 at 12:20
0
Popen(["command", "-opt", "value", "arg1", "arg2" ...], stdout=PIPE)

You are not using the Popen function the right way. Here is a short example considering your script :

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

You shoud take a look to the subprocess documentation (help(subprocess) in an interpreter)

FunkySayu
  • 7,641
  • 10
  • 38
  • 61