Найти - Пользователи
Полная версия: subprocess.call()
Начало » Python для новичков » subprocess.call()
1
tbazadaykin
Сначала предыстория.
В линуксе есть утилита find. У нее есть параметр -exec который позволяет для каждого выбранного файла выполнить команду. Например пишем:
find *.flv \( -type f -o -type l \) -newermt '7/01/2012' -and -not -newermt '7/31/2012' -exec rm -v {} \;
Она найдет все файлы flv с датой изменения между 1 и 31 июля и удаляет каждый найденный.

Теперь история.
Есть у меня скрипт который делает пакетную обработку файлов (т.е. много файлов разом). Мне надо дать возможность при вызове этого скрипта выполнить команду (по аналогии с вышеприведенным примером) для каждого файла в случае успешной обработки файла, и в случае неудачной обработки. Например:
python my_script.py --on_sucess rm -v {} --on_faild echo "Faild" /home/user/files/*.xml

Сейчас делаю как-то так
from subprocess import call
...
for f in arguments.source:
  try:
    process(f)
    if arguments.on_sucess:
      call(arguments.on_sucess.replace('%fn',f),shell=True)
  except:
    if arguments.on_faild:
      call(arguments.on_faild.replace('%fn',f),shell=True)

Ну и вызов
python my_script.py --on_sucess 'rm %fn' --on_faild 'echo "Faild %fn"' /home/usr/files/*.xml

Не нравится что параметры –on_sucess и –on_faild приходится передавать строками. Вот как бы сделать что бы не строками?
doza_and
почитайте про argparse. Но в общем случае необходимо продумать входной язык
python my_script.py --on_sucess 'rm --on_sucess %s' --on_faild ...
Как вы в этом случае при отсутствии кавычек будете отличать опции вызываемой команды от опций my_script.py ?

Может вам просто xargs поможет?

Ну и собственно зачем вам find написанный на питоне? Не проще просто find использовать?
py.user.next
doza_and
Не проще просто find использовать?
там, похоже, кроссплатформенный скрипт

tbazadaykin
Не нравится что параметры –on_sucess и –on_faild приходится передавать строками.
да вообще, из командной строки не должно быть способа влиять на внутренности скрипта, это же что-то вроде eval() получается

tbazadaykin
echo "Faild"
а что такое “Faild” ? имелось в виду “failed” ?

зарегистрируй лучше определённые команды, а параметр к команде подавай отдельной опцией
tbazadaykin
doza_and
Ну и собственно зачем вам find написанный на питоне? Не проще просто find использовать?
find просто в качестве примера того как хотелось бы реализовать вызов команд, my_script.py не дублирует функционал find.

py.user.next
а что такое “Faild” ? имелось в виду “failed” ?
Да, разумеется. Опечатался.

doza_and
Как вы в этом случае при отсутствии кавычек будете отличать опции вызываемой команды от опций my_script.py ?
Ну find же отличает как-то.
doza_and
tbazadaykin
Ну find же отличает как-то.
У него предопределенные имена опций. Но при этом find внутри find не вызовешь.
За словами потерялось
посмотрите:
http://docs.python.org/dev/library/argparse.html
py.user.next
doza_and
Но при этом find внутри find не вызовешь.
[guest@localhost ~]$ find /tmp -type d -name 'orbit*'
/tmp/orbit-guest
[guest@localhost ~]$
[guest@localhost ~]$ find /tmp -type d -name 'orbit*' -exec find {} -maxdepth 1 -type f \;
/tmp/orbit-guest/bonobo-activation-server-7f729dc53f9099eabd3ff9bd514c0e94-ior
/tmp/orbit-guest/bonobo-activation-register-7f729dc53f9099eabd3ff9bd514c0e94.lock
[guest@localhost ~]$
tbazadaykin
Собственно, обратившись к справке по find стало понятно как он вычленяет команду и ее параметры:
-exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encountered. The string `{}' is replaced by the current file name being processed…
Теперь осталось понять как это реализовать при помощи argparse.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB