我想知道是否有人对此有任何见解。我有一个bash脚本,应该将我的ssh密钥放到远程计算机上。该脚本摘自here,
#!/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"
这很有效。等效的python脚本应该是
#!/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()})
但在这种情况下,我明白了
sh: line 1: >> ~/.ssh/authorized_keys; chmod 644 ~/.ssh/authorized_keys: No
such file or directory
我做错了什么?我试图逃避最内层的引用,但同样的错误信息......请提前感谢您的回复。
答案 0 :(得分:5)
你有一个严肃的问题 - 因为os.system
没有按照你期望的方式行事 - 但是,你应该认真地重新思考这个方法。
你正在启动一个Python解释器 - 然后,通过os.system
告诉Python解释器启动一个shell!在现代Python中根本不应该使用os.system
(subprocess
是完全替代的...)但是在这种用例中使用任何启动shell实例的Python调用都非常愚蠢。 / p>
现在,就实际的即时问题而言 - 看看你的引号是如何嵌套的。您将看到mkdir
中正在关闭echo
之前启动的引号,允许您将命令拆分到您不想要的位置。
以下修复了这个直接问题,但仍然非常糟糕(不必要地启动子shell,没有正确检查输出状态,应该转换为使用subprocess.Popen()
):
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()
})