Подстановочный знак не работает в вызове подпроцесса с использованием shlex


Язык: Python v2. 6. 2

OS: 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

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

МВ: 0653-401 не удается переименовать /работа/testrestore/производство/* для /работы/TESTC/*: файл или каталог в имени пути не существует.

Похоже, что unix теперь пытается переместить файл с именем *, а не затем используйте * в качестве подстановочного знака. Является ли это типичным поведением шлекса?

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

1 4

1 ответ:

Для замены * на то, что это означает, вам нужна либо оболочка, либо модуль 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)

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

cmd = 'sudo rm -rf'
basearg = shlex.split(cmd)
arg = basearg + glob.glob(path+"/*")