'Pexpect won't pass commands to Panduit PDU (Smartzone G5) via SSH
Problem
I've got a program using "Pexpect" to send commands over SSH. Its purpose is to SSH into a Panduit PDU (smartzone G5) and turn off port 1.
I can SSH into the PDU and run dev outlet 1 1 off and get the port to turn off, but it doesn't work when I try to run the same command from my program. It puzzles me as this method is no different than me logging in via SSH using iterm and typing. Is this a me problem or just how the PDU behaves?
What I've Tried
I've tested pexpect thoroughly on a Linux server using mkdir and touch to create directories and files so I know it works without issue there, but when I use it on the Panduit PDU the PDU ignores the commands.
I use time.sleep() to allow the PDU to catch up as it is a slow system and seems to have a queue for multiple commands.
It's not a module issue or interpreter issue or anything silly like that; the program itself is fine. (Though I'm sure it's not up to standards or safe but who cares if I can't get the program to work in the first place seriously.)
Why Pexpect?
I must use Pexpect as Paramiko and Fabric don't work for this particular connection.
I must specify ssh -F /dev/null admin@ipaddress otherwise the PDU rejects the SSH session and I cannot get pxssh or fabric or paramiko to do this so that's why I don't use them.
I'm aware of stuff like .set_missing_host_key_policy(paramiko.AutoAddPolicy()) for Paramiko and s = pxssh.pxssh(options={"StrictHostKeyChecking": "no", "UserKnownHostsFile": "/dev/null"}) and they do not work. Hence Pexpect.
Code
import os
import pexpect
import time
import sys
server_ip = "192.168.0.1"
server_user = "admin"
server_pass = "password"
child = pexpect.spawn('bash')
child.logfile_read = sys.stdout.buffer
child.expect('')
# This is the only way to access the PDU, Paramiko wont work either.
child.sendline('ssh -F /dev/null %s@%s -oStrictHostKeyChecking=no' % (server_user, server_ip))
child.expect("[email protected]'s password:")
child.sendline(server_pass)
child.expect('PANDUIT>')
time.sleep(3) # Wait for PDU to catch up or it wont recognise the command
child.sendline('dev outlet 1 1 off') # Power off port 1
print('\nfinished') # \n is there otherwise it gets sucked into the stdout
For reference this is what happens when I use Iterm to manually connect and enter commands, it works perfectly.
I've tried to use child.expect('SUCCESS') but it can't be seen. The only thing pexpect seems to be able to find inside the PDU is child.expect('\n') which I think may be from a buffer or something.
~/Documents ❯ ssh -F /dev/null [email protected]
[email protected]'s password:
Type ? for command listing
sys PDU system configure and setting
net PDU net application configure and setting
usr PDU user operation
dev PDU device setting
pwr PDU power setting
PANDUIT>dev outlet 1 1 off
SUCCESS
And this is what my code outputs:
~/Documents❯ python3 code.py
ssh -F /dev/null [email protected] -oStrictHostKeyChecking=no
The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
bash-3.2$ ssh -F /dev/null [email protected] -oStrictHostKeyChecking=no
[email protected]'s password:
Type ? for command listing
sys PDU system configure and setting
net PDU net application configure and setting
usr PDU user operation
dev PDU device setting
pwr PDU power setting
PANDUIT>
finished
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
