python shell命令 - 为什么它不起作用?

时间:2009-09-22 01:51:11

标签: python shell

我想知道是否有人对此有任何见解。我有一个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

我做错了什么?我试图逃避最内层的引用,但同样的错误信息......请提前感谢您的回复。

1 个答案:

答案 0 :(得分:5)

你有一个严肃的问题 - 因为os.system没有按照你期望的方式行事 - 但是,你应该认真地重新思考这个方法。

你正在启动一个Python解释器 - 然后,通过os.system告诉Python解释器启动一个shell!在现代Python中根本不应该使用os.systemsubprocess是完全替代的...)但是在这种用例中使用任何启动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()
})