Команда оболочки Python - почему она не работает? - PullRequest
1 голос
/ 22 сентября 2009

Интересно, есть ли у кого-нибудь понимание этого. У меня есть скрипт 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 голосов
/ 22 сентября 2009

У вас есть серьезный вопрос - в том, что os.system ведет себя не так, как вы ожидаете, - но вы также должны серьезно переосмыслить подход в целом.

Вы запускаете интерпретатор Python - но затем через os.system говорите, что интерпретатор Python запускает оболочку! os.system не должен использоваться вообще в современном Python (subprocess - полная замена) ... но использование любого вызова Python, который запускает экземпляр оболочки, является исключительно глупым в этом случае использования.

Теперь, с точки зрения актуальной, неотложной проблемы - посмотрите, как вложены ваши кавычки. Вы увидите, что кавычка, которую вы начинаете до mkdir, закрывается в echo, что позволяет разделить вашу команду в месте, которое вы не собираетесь.

Следующее исправляет эту непосредственную проблему, но все еще ужасно и плохо (запускает подоболочку без необходимости, не проверяет должным образом состояние вывода и должно быть преобразовано для использования 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()
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...