Reputation: 329
Other posts touch on the topic but I'm still not clear as to why this works:
command = "echo /sbin/poweroff | ssh admin@" + address
shutcmd = subprocess.Popen(command, stdout = subprocess.PIPE, shell=True)
and this doesn't work:
shutcmd = subprocess.Popen(["echo", "/sbin/poweroff" "|" "ssh", "admin@",address], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
How would you do this correctly?
Upvotes: 2
Views: 3909
Reputation: 19030
Because |
is shell syntax and semantics.
You would simulate this by doing:
from subprocess import Popen, PIPE, STDOUT
user = "root"
host = "1.2.3.4"
p = Popen(
["ssh", "{}@{}".format(user, host)],
stdin=PIPE, stdout=PIPE, stderr=STDOUT
)
stdout, stderr = p.communicate("/sbin/poweroff\n")
However it's even simpler to just issue the command itself as an argument to ssh
:
p = Popen(
["ssh", "{}@{}".format(user, host), "/sbin/poweroff"],
)
p.wait()
As an aside; the reason your first example works at all is because of shell=True
. A shell is involved to run your "piece of shell" so therefore the new shell that is spawned has it's own set of fd triples for stdin, stdout and stderr; so echo | ssh
work.
See: Pipeline (UNIX)
Upvotes: 3
Reputation: 14490
You can just pass the command to run to ssh, you don't have to pipe into it.
Try
shutcmd = subprocess.Popen(['ssh', 'admin@' + address, '/sbin/poweroff'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Upvotes: 1