Подстановочный знак не работает в вызове подпроцесса с использованием shlex - PullRequest
5 голосов
/ 23 августа 2011

Язык: Python v2.6.2

ОС: AIX 5.3

Я использую Python для восстановления некоторых файлов из резервной копии в тестовую систему - все команды вызываются описанным ниже способом, однако некоторые просто не хотят работать.

#!/usr/bin/python
import subprocess, shlex

cmd = 'sudo rm -rf /work/TEST/*'
arg = shlex.split(cmd)

# This does not work
p = subprocess.Popen(arg)

# This, however, works just fine
p = subprocess.Popen(cmd, shell=True)

Если я удаляю * из команд, они работают нормально (ну, они работают как надо без подстановочных знаков, что, к сожалению, не то, что я хочу).

Я действительно не хочу использовать shell = True по очевидным причинам безопасности, однако есть пара других команд, которые в основном делают то же самое. Если в команде есть подстановочный знак, он просто не будет работать - он выполняется без ошибок, просто ничего не делает.

Интересно, что следующая команда (разбирается через shlex):

sudo mv /work/testrestore/production/* /work/TESTC

Производит следующее:

mv: 0653-401 Невозможно переименовать / work / testrestore / production / * в / work / TESTC / *: файл или каталог с именем пути не существует.

Как будто unix сейчас пытается переместить файл с именем * вместо использования * в качестве подстановочного знака. Это типичное поведение шлекс?

Редактировать: я пытался экранировать * с помощью \, также пытался перейти от одинарных кавычек к двойным ... не то чтобы я ожидал, что это что-то сделает.

1 Ответ

5 голосов
/ 23 августа 2011

Для замены * на то, что это означает, вам нужна либо оболочка, либо модуль glob. Таким образом, самый простой способ будет shell=True (если команда постоянная, я не вижу никаких дыр в безопасности).

Другой подход будет

#!/usr/bin/python
import subprocess
import shlex
import glob

cmd = 'sudo rm -rf /work/TEST/*'
arg = shlex.split(cmd)
arg = arg[:-1] + glob.glob(arg[-1])

# This should work now
p = subprocess.Popen(arg)

или, если вы все же добавите путь самостоятельно,

* * 1010
...