Python shell命令 - 为什么不工作?

1 投票
1 回答
1985 浏览
提问于 2025-04-15 14:29

我想知道有没有人能给我一些见解。我有一个bash脚本,应该把我的ssh密钥放到远程机器上。这个脚本是从这里改编过来的,内容如下:

#!/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 个回答

5

你遇到了一个严重的问题——就是os.system的表现和你预期的不一样——不过,你也应该认真考虑一下整体的方法。

你在启动一个Python解释器,但接着又通过os.system让这个Python解释器去启动一个shell!在现代Python中根本不应该使用os.systemsubprocess可以完全替代它)……而且在这种情况下,使用任何会启动shell的Python调用都是非常不明智的。

现在,关于你眼前的具体问题——看看你的引号是怎么嵌套的。你会发现,在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()
})

撰写回答