I have a perl one liner that appends a string at the end of a particular line and it works when I run the one liner on the host. For instance, I'm looking to append 'boy857sr xxxxxxx' at the end of a line that starts with 'AllowUsers'
perl -pi.bak -e 's/^(AllowUsers.*)/\1 boy857sr xxxxxxx/g;' /etc/ssh/sshd_config
Works perfectly!
AllowUsers boy857bt soladmin svc-Orion_SAM solarw boy857lj boy806nk boy806sk boy857sr xxxxxxx
But when I run it inside a python script, it wipes out the 'AllowUsers' line and add another line, look below:
#RSAAuthentication yes
^A kn857sr xxxxxxx
Here is the python script.
import pxssh
my_list=[
"server121"
]
for i in my_list:
s = pxssh.pxssh(timeout=15, maxread=2000000)
s.SSH_OPTS += "-o StrictHostKeyChecking=no"
s.SSH_OPTS += "-o UserKnownHostsFile=/dev/null"
s.login(i,'username','password')
print (i)
s.sendline('/usr/local/bin/sudo su -')
s.expect('Password: ')
s.sendline('xxxxxxx')
s.prompt()
print s.before
s.sendline('perl -pi.bak -e \'s/^(AllowUsers.*)/\1 boy857sr xxxxxxx/g;\'
/etc/ssh/sshd_config')
s.prompt()
print s.before
s.sendline('exit')
s.logout()
Python interprets the \1 in your replacement string as the character 0x01 (which often renders as ^A).
Moreover, using \1, \2 etc. in Perl regexes is reserved to the left hand side of the s/// operator, i.e. to the pattern. On the right hand side (the replacement string) you should use $1, $2 etc. instead.
From the docs
... It is at this step that
\1is begrudgingly converted to$1in the replacement text ofs///, in order to correct the incorrigible sed hackers who haven't picked up the saner idiom yet. A warning is emitted if theuse warningspragma or the-wcommand-line flag (that is, the$^Wvariable) was set.
So:
s.sendline('perl -pi.bak -e \'s/^(AllowUsers.*)/$1 boy857sr xxxxxxx/g;\' /etc/ssh/sshd_config')
should do the trick.
Update: Eventually I found the reference page for \1 vs. $1 (thanks to this post).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With