sql >> Databáze >  >> RDS >> Mysql

Proč subprocess.Popen nečeká na ukončení podřízeného procesu?

subprocess.Popen , když je vytvořena instance, spustí program. Nečeká na to – spustí jej na pozadí, jako byste zadali cmd & ve skořápce. Takže ve výše uvedeném kódu jste v podstatě definovali podmínku sporu – pokud se vložky dokážou dokončit včas, bude to vypadat normálně, ale pokud ne, dostanete neočekávaný výstup. Nečekáte na svůj první run() Pokud chcete PID dokončit, jednoduše vracíte jeho Popen instance a pokračování.

Nejsem si jistý, jak toto chování odporuje dokumentaci, protože na Popenu je několik velmi jasných metod, které, jak se zdá, naznačují, že se na něj nečeká, jako:

Popen.wait()
  Wait for child process to terminate. Set and return returncode attribute.

Souhlasím však s tím, že dokumentaci k tomuto modulu lze zlepšit.

Chcete-li počkat na dokončení programu, doporučuji použít subprocess 's pohodlný způsob, subprocess.call nebo pomocí communicate na Popen objekt (pro případ, kdy potřebujete stdout). Už to děláte pro svůj druhý hovor.

### START MAIN
# copy some rows from a source table to a destination table
# note that the destination table is empty when this script is run
cmd = 'mysql -u ve --skip-column-names --batch --execute="insert into destination (select * from source limit 100000)" test'
subprocess.call(cmd)

# check to see how many rows exist in the destination table
cmd = 'mysql -u ve --skip-column-names --batch --execute="select count(*) from destination" test'
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
try: count = (int(process.communicate()[0][:-1]))
except: count = 0

Navíc ve většině případů nemusíte spouštět příkaz v shellu. Toto je jeden z těchto případů, ale budete muset svůj příkaz přepsat jako sekvenci. Pokud to uděláte tímto způsobem, také vám umožní vyhnout se tradičnímu vstřikování shellu a méně se starat o citování, jako například:

prog = ["mysql", "-u", "ve", "--execute", 'insert into foo values ("snargle", 2)']
subprocess.call(prog)

To bude dokonce fungovat a nebude vstřikováno tak, jak byste očekávali:

prog = ["printf", "%s", "<", "/etc/passwd"]
subprocess.call(prog)

Zkuste to interaktivně. Vyhnete se možnostem vkládání shellu, zvláště pokud přijímáte uživatelský vstup. Mám podezření, že pro komunikaci s podprocesem používáte méně úžasnou řetězcovou metodu, protože jste měli potíže s uvedením sekvencí do práce :^)



  1. Řetězení kolekcí v PLSQL

  2. Restartování transakce v MySQL po uváznutí

  3. Při připojování ke vzdálenému mému SQL mi byl odepřen přístup pro uživatele [chráněno e-mailem] (Pomocí hesla:Ano)

  4. JavaScript Před smazáním potvrďte pomocí PHP/MYSQL