I wonder if anyone has any insights into this. I have a bash script that should put my ssh key onto a remote machine. Adopted from here, the script reads,
#!/usr/bin/sh
REMOTEHOST=user@remote
KEY="$HOME/.ssh/id_rsa.pub"
KEYCODE=`cat $KEY`
ssh -q $REMOTEHOST "mkdir ~/.ssh 2>/dev/null; chmod 700 ~/.ssh; echo "$KEYCODE" >> ~/.ssh/authorized_keys; chmod 644 ~/.ssh/authorized_keys"
This works. The equivalent python script should be
#!/usr/bin/python
import os
os.system('ssh -q %(REMOTEHOST)s "mkdir ~/.ssh 2>/dev/null; chmod 700 ~/.ssh; echo "%(KEYCODE)s" >> ~/.ssh/authorized_keys; chmod 644 ~/.ssh/authorized_keys"' %
{'REMOTEHOST':'user@remote',
'KEYCODE':open(os.path.join(os.environ['HOME'],
'.ssh/id_rsa.pub'),'r').read()})
But in this case, I get that
sh: line 1: >> ~/.ssh/authorized_keys; chmod 644 ~/.ssh/authorized_keys: No
such file or directory
What am I doing wrong? I tried escaping the inner-most quotes but same error message… Thank you in advance for your responses.
You have a serious question — in that
os.systemisn’t behaving the way you expect it to — but also, you should seriously rethink the approach as a whole.You’re launching a Python interpreter — but then, via
os.system, telling that Python interpreter to launch a shell!os.systemshouldn’t be used at all in modern Python (subprocessis a complete replacement)… but using any Python call which starts a shell instance is exceptionally silly in this kind of use case.Now, in terms of the actual, immediate problem — look at how your quotation marks are nesting. You’ll see that the quote you’re starting before
mkdiris being closed in theecho, allowing your command to be split in a spot you don’t intend.The following fixes this immediate issue, but is still awful and evil (starts a subshell unnecessarily, doesn’t properly check output status, and should be converted to use
subprocess.Popen()):