Когда shell = True , args[0]
- команда, которая должна быть выполнена, а args[1:]
- аргументы, передаваемые sh
.Вы хотите, чтобы -p
и restore_filepath
были переданы pv
, а не sh
.Так что используйте shell=False
.То же самое относится и к вашему другому вызову subprocess.Popen
.
Так как с shell=True
, pv
не получает никаких аргументов, поэтому он зависает, потому что все еще ждал имени файла.Итак, снова, решение состоит в том, чтобы использовать shell=False
.
Также обратите внимание, что когда заменяет конвейер оболочки , вы должны закрыть stdout
в первом процессе, чтобы он мог получить SIGPIPE, еслиВторой процесс существует.Это позволяет некоторым программам (работающим с SIGPIPE) более корректно завершать работу, если конвейер прерван.
pv = subprocess.Popen(
["pv", "-f", restore_filepath],
shell=False, # optional, since this is the default
bufsize=1,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
universal_newlines=True,
)
mysql = subprocess.Popen(
["mysql",
"-u{}".format(db_user),
"-p{}".format(db_pass),
db_name],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
stdin=pv.stdout,
)
pv.stdout.close() # Allow pv to receive a SIGPIPE if mysql exits.
for line in pv.stderr:
print("hello")
sys.stdout.write("\r" + line.rstrip("\n"))
sys.stdout.flush()