1

Ok, im trying to understand how to use subprocess.

I've made a little problem for practice and i just can't do it. what i want to do is: ping google then do a "cd" command

so basically i want to see the ping command return values and then the directory where my program is

This maybe to much info, so you can just jump to the last code section. ______________________________Jump______________________________________

I have tried many versions of a code. I managed to half do it with "run" command but that returns a "CompletedProcess" and i can't use that.

So first try was pinging google

result=subprocess.run('ping google.com', stdout=subprocess.PIPE)
print(result.stdout.decode('utf-8'))

this worked fine, then i susbtituted "'ping google.com'" for "'cd', shell=True" And finnaly substituted cd for dir, and decode could not decode the output (why?).

Ok so after that i tried:

result=subprocess.run(['cd ..'], shell=True, stdout=subprocess.PIPE)
result.run(['cd'], shell=True, stdout=subprocess.PIPE)
print(result.stdout.decode('utf-8'))

And got:

AttributeError: 'CompletedProcess' object has no attribute 'run'

as expected. So this lead me to Popen, so i started all over with it:

result=subprocess.Popen('ping google.com',  stdout=subprocess.PIPE)
print(result.communicate()[0].decode('utf-8'))

_____________________Stop Jump____________________________

Now i want to send the "cd" after the ping, i have tried multiple ways of doing this, such as:

result=subprocess.Popen('ping google.com',shell=True, stdin=subprocess.PIPE,stdout=subprocess.PIPE)
a='cd\n'
result.communicate(a.encode('utf-8'))
print(result.communicate()[0].decode('utf-8'))

this prints just the ping. I tried removing "[0].decode('utf-8')" - no cd output

I expected to see the ping result, then the cd output, what can i do?

Ultimately i want to run several commands that depend on the previous output.

Bonus question: I want to apply a program using Popen to a raspbian terminal, it's the same correct?

Edit: my question is not about cd, its about running multiple commands in the same terminal, cd could be just pinging a different ip

wrong1man
  • 133
  • 2
  • 10
  • What do you mean by "send the `cd`"? What is your goal with the `cd`? Changing the working directory of the child doesn't change the parent script. `run()` has a `cwd` parameter to set the initial directory for the child. If you want to cd while running the child program then it should be a script that does it, or perhaps "cd whatever;ping google.com". – tdelaney Apr 14 '18 at 20:27
  • Possible duplicate of [Subprocess changing directory](https://stackoverflow.com/questions/21406887/subprocess-changing-directory) – tripleee Apr 14 '18 at 20:39
  • `ping` is not reading commands on standard input; so putting the `cd` *there* is doubly pointless. (The nominated duplicate tells you why this is pointless in the first place.) – tripleee Apr 14 '18 at 20:40
  • Read my edit - this is not about the cd, cd could be any other command (isnt even about the ping - just about understanding how to use subprocess to run multiple commands on a shell) – wrong1man Apr 14 '18 at 20:45
  • `shell=True` doesn't run an *interactive* shell; it just creates a subprocess which runs a shell which runs the commands you give it when you start it, and then exits. – tripleee Apr 14 '18 at 20:45

1 Answers1

0

If you're trying to do two commands through the same terminal you have to start the shell first and then feed in the commands one by one:

import subprocess
p = subprocess.Popen('cmd.exe', stdin=subprocess.PIPE,
         stdout=subprocess.PIPE)
p.stdin.write(b'ping www.google.com' + '\n') #b in front to denote bytes object
p.stdin.write(b'cd ..' + b'\n') #stdin doesn't take strings
p.stdin.close()
a = p.stdout.read()
for i in a.split(b'\n'):
    print(i)

And you'll get something like this:

b'Microsoft Windows [Version 10.0.16299.371]\r'
b'(c) 2017 Microsoft Corporation. All rights reserved.\r'
b'\r'
b'C:\\Users\\Jason\\.PyCharmCE2017.3\\config\\scratches>ping www.google.com'
b'\r'
b'Pinging www.google.com [172.217.12.196] with 32 bytes of data:\r'
b'Reply from 172.217.12.196: bytes=32 time=5ms TTL=56\r'
b'Reply from 172.217.12.196: bytes=32 time=5ms TTL=56\r'
b'Reply from 172.217.12.196: bytes=32 time=6ms TTL=56\r'
b'Reply from 172.217.12.196: bytes=32 time=7ms TTL=56\r'
b'\r'
b'Ping statistics for 172.217.12.196:\r'
b'    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r'
b'Approximate round trip times in milli-seconds:\r'
b'    Minimum = 5ms, Maximum = 7ms, Average = 5ms\r'
b'\r'
b'C:\\Users\\Jason\\.PyCharmCE2017.3\\config\\scratches>cd ..'
b'\r'
b'C:\\Users\\Jason\\.PyCharmCE2017.3\\config>'
Primusa
  • 13,136
  • 3
  • 33
  • 53
  • Thank you that is exactly what i wanted to know! I'll test it in a bit! – wrong1man Apr 14 '18 at 20:47
  • Hi!, i tested it out. You solved my first problem, which was running multiple commands on the same shell. but the printing method doesnt seem to be working, - "a is not defined" i tried changing that "a" but since i dont understand what its beeing done there i can't fix it. I can use comunicate to print the results but that closes the shell and that is not what i intended... – wrong1man Apr 14 '18 at 21:34
  • My bad I forgot a line it's fixed now – Primusa Apr 14 '18 at 22:09
  • i get "AttributeError: 'SubprocessPopen' object has no attribute 'split'" - my problem right now is stdout doesnt seem to be working – wrong1man Apr 14 '18 at 22:57
  • ahh so that means that what i want to do is impossible? i want to be able to write something back in it after i printed it out... And i have to close it to print it. Can i open it back up? – wrong1man Apr 14 '18 at 23:54
  • I wouldn't call it impossible but I have no idea how to do it. Do you need all of them to be done through the same terminal? – Primusa Apr 14 '18 at 23:56
  • Ahh it's okay, i need to do a series of commands on a program, like checking for saved password and asking for login credentials, etc (im basically doing an gui for it).. so i can close the terminal and open a new one that takes a path that depends on the previous output! – wrong1man Apr 15 '18 at 00:31
  • Sounds like you are really looking for `pexpect`. – tripleee Apr 15 '18 at 04:55
  • That sounds very promising! Thabks for the tip! – wrong1man Apr 15 '18 at 13:27
  • @tripleee hey i got it to work with pexpect, thank you very much!! One question which is best to run a program indefinitely, pexpect or subprocess? – wrong1man Apr 17 '18 at 01:40
  • That's not really a well-defined question, but in the absence of any context, I would say subprocess. – tripleee Apr 17 '18 at 04:13