Подстановочный знак не работает в вызове подпроцесса с использованием 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 ответ:
Для замены
*
на то, что это означает, вам нужна либо оболочка, либо модуль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+"/*")