2013-07-15 3 views
0

Я создаю файл, а затем делаю diff на нем.Выполняется ли код python в порядке

Я хочу сделать diff на файл, который создан на предыдущем шаге, но я получаю ошибку, что файл не существует.

Это мой код

os.popen("mysqldump --login-path=server1_mysql -e --opt --skip-lock-tables --skip-extended-insert -c %s > %s.sql" % (database, filename)) 
os.popen("diff %s %s > %s" % (weekly, filename, filename+".PATCH")) 

ответ

1

os.popen() был deprecated since version 2.6. Однако, чтобы заставить ваш код работать, вы должны дождаться завершения первого процесса (и файла вывода, который должен быть создан), прежде чем запускать второй.

Статус выхода первой команды доступен как возвращаемое значение close() метода объекта файла возвращается, так что вы можете проверить, что, прежде чем продолжить, а именно:

pipe = os.popen("mysqldump --login-path=server1_mysql -e --opt " 
       "--skip-lock-tables --skip-extended-insert -c %s > %s.sql" % 
       (database, filename)) 
if pipe.close() is None: # no errors? 
    os.popen("diff %s %s > %s" % (weekly, filename, filename+".PATCH")) 
+0

Спасибо, чувак, работает только код ur. Это может быть не идеально, но это сработало – user22

+0

Рад слышать, что, однако, вы действительно должны преобразовать свой код в какой-то момент, чтобы использовать 'subprocess.call()' - это определенно лучше и обычно относительно проще в использовании. – martineau

5

os.popen is deprecated. Use the subprocess module. subprocess.call блокирует основной процесс, пока команда не будет завершена. Вы должны проверить код возврата, retval, в случае возникновения ошибки при выполнении команды mysqldump. В этом случае, вы не можете продолжать с diff:

import subprocess 
import shlex 
with open("{f}.sql".format(f=filename), 'w') as fout: 
    retval = subprocess.call(
     shlex.split(
      """mysqldump --login-path=server1_mysql -e --opt --skip-lock-tables 
      --skip-extended-insert -c %s""" % (database,)), 
     stdout=fout) 

if not retval == 0: 
    raise Exception('Error executing command: {r}'.format(r=retval)) 
else: 
    with open("{f}.PATCH".format(f=filename), 'w') as fout: 
     retval = subprocess.call(
      shlex.split("diff {w} {f}".format(w=weekly, f=filename)), 
      stdout=fout) 
+0

В этом случае нет ничего 'общаться', поэтому проще просто вызвать' proc.wait() '. Но в целом, да (поддержано). – torek

+0

@torek: True. Благодаря! – unutbu

+0

О, еще одна вещь, которую я заметил только сейчас: использование 'shlex.split' обычно хорошо, но в этом случае строка ожидает, что оболочка сделает перенаправление, поэтому вам понадобится' shell = True' и не захотите разделить строка. Или (более безопасно, чем пытаться указать метасимволы оболочки), откройте выходной файл в Python и передайте его как 'stdout =' в вызове подпроцесса. – torek

0

супер простой способ заключается в использовании активного ожидания:

os.popen("mysqldump --login-path=server1_mysql -e --opt --skip-lock-tables --skip-extended-insert -c %s > %s.sql" % (database, filename)) 
while not os.path.isfile(filename): 
    sleep(0.05) # or some other interval 
os.popen("diff %s %s > %s" % (weekly, filename, filename+".PATCH")) 

EDIT:

Используйте с осторожностью, оставляет потому что условие, которое проверяется, только то, что файл существует, а не предыдущий процесс завершен.

+1

Занятое ожидание * * простое, но ненужное; и это уходит в состояние гонки: diff может начаться примерно в то время, когда mysqldump запустился, но до завершения mysqldump. – torek

+0

Правда, это было, наверное, немного _too_ просто. Я все еще думаю, что изучение простых (_old school_, если вам нравится) решений, таких как ожидание, является полезной вещью, и в некоторых случаях это по-прежнему необходимо. Но я согласен, что в этом случае он субоптимален. – Henrik

Смежные вопросы