问题
I'm having trouble programmatically running a local script over ssh.
I'm unsure if this is a problem with the shell variable substitution on the local host.
When manually running,
ssh monit@server1 'bash -s' < /u02/splunk/splunk/etc/apps/Splunk_TA_nix/bin/cpu.sh
I get the expected output,
CPU pctUser pctNice pctSystem pctIowait pctIdle
all 11.21 0.00 1.50 0.31 86.98
0 0.00 0.00 0.00 0.00 100.00
1 3.00 0.00 1.00 0.00 96.00 ....
but I get
bash: /u02/splunk/splunk/etc/apps/Splunk_TA_nix/bin/cpu.sh: No such file or directory
when running the following code,
splunk_bin_dir = '/u02/splunk/splunk/etc/apps/Splunk_TA_nix/bin'
hostname = 'server1'
username = 'monit'
password = 'monit#_'
command = "/usr/bin/ssh %(username)s@%(hostname)s 'bash -s' < %(splunk_bin_dir)s/cpu.sh" % locals()
print command
ssh_new_conn = 'Are you sure you want to continue connecting'
p = pexpect.spawn(command, timeout=360)
# Handles the 3 possible connection outcomes:
# a) Ssh to the remote host for the first time, triggering 'Are you sure you want to continue connecting'
# b) ask you for password
# c) No password is needed at all, because you already have the key.
i = p.expect([ssh_new_conn,'[pP]assword:',pexpect.EOF])
print ' Initial pexpect command output: ', i
if i == 0:
# send 'yes'
p.sendline('yes')
i = p.expect(['[pP]assword:',pexpect.EOF])
print 'sent yes. pexpect command output', i
if i == 0:
# send the password
p.sendline(password)
p.expect(pexpect.EOF)
elif i == 1:
# send the password
p.sendline(password)
p.expect(pexpect.EOF)
elif i == 2:
print "pexpect faced key or connection timeout"
pass
print p.before
These are the printed outputs,
/usr/bin/ssh monit@server1 'bash -s' < /u02/splunk/splunk/etc/apps/Splunk_TA_nix/bin/cpu.sh
Initial pexpect command output: 1
bash: /u02/splunk/splunk/etc/apps/Splunk_TA_nix/bin/cpu.sh: No such file or directory
pexpect is bumping into the [pP]assword line so I guess the password is being correctly passed,
回答1:
Here the note from pexpect manual:
Remember that Pexpect does NOT interpret shell meta characters such as redirect, pipe, or wild cards (>, |, or *). This is a common mistake. If you want to run a command and pipe it through another command then you must also start a shell.
This is the working line
command = """/bin/bash -c "/usr/bin/ssh %(username)s@%(hostname)s 'bash -s' < %(splunk_bin_dir)s/cpu.sh" """ % locals()
来源:https://stackoverflow.com/questions/10207486/pexpect-run-script-sh-over-ssh