Не удается переименовать исполняемые файлы - PullRequest
0 голосов
/ 04 мая 2018

Я выполняю команду через ssh в python.

os.system("ssh atl.LB99@172.31.54.76 'bash --login -c "if [[ -e filepath && ! -L filepath ]];then mv filepath filepath.backup; fi;"'")

У меня есть список путей к файлам, выполняемых с помощью этой команды. Цель этого scommand - добавить «.backup» после исходного имени файла. Однако это не всегда работает. Имена файлов заканчиваются на (которые являются исполняемыми файлами. не является частью имени файла, это просто говорит о том, что этот файл является исполняемым файлом), не меняют свое имя на «filename.backup». И эти файлы имеют достаточные разрешения (например, -rwxrwxr-x).

Система Linux, а оболочка bash.

Какой ключ для решения этой проблемы?

1 Ответ

0 голосов
/ 04 мая 2018

Без ошибок и дополнительной сложности это может выглядеть так:

import subprocess
try:
    from pipes import quote # Python 2.x
except ImportError:
    from shlex import quote # Python 3.x

# does not need to be shell-quoted; path='/path/to/filename with spaces' is legal
path = "filepath"

cmd = '''
    path=%(path)s

    # this is all POSIX-compliant syntax below, so we don't need to rely on bash
    if [ ! -L "$path" ] && [ -e "$path" ]; then
        mv -- "${path}" "$path.backup"
    fi
''' % {"path": quote(path)}

subprocess.Popen(['ssh', 'atl.LB99@172.31.54.76', cmd])

Какие ключевые моменты здесь?

  • Количество оболочек должно быть сведено к минимуму, или необходимо приложить значительные усилия для обеспечения безопасного выхода из путей. В этом случае мы идем по первому пути: поскольку мы не используем os.system() или аргумент shell=True для subprocess.Popen(), локальная оболочка отсутствует. Поскольку мы не используем bash -c, существует только одна удаленная оболочка - та, которая непосредственно запускается ssh, а не дополнительная, запускаемая , которая shell.
  • Когда мы делаем подставляем параметризованное значение (в данном случае имя файла) в скрипт, сгенерированный для запуска оболочкой, мы используем shlex.quote() в Python 3 или pipes.quote() в Python 2 для избежать этого.
  • Когда мы передаем скрипт оболочки по проводам, мы проверяем его правильный синтаксис - это означает, что в этом случае блок if должен заканчиваться fi. http://shellcheck.net/ является полезным ресурсом для такой проверки.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...