Mysql
 sql >> база данни >  >> RDS >> Mysql

Защо subprocess.Popen не чака докато дъщерният процес приключи?

subprocess.Popen , когато се инстанцира, изпълнява програмата. Той обаче не го изчаква - той го задейства във фонов режим, сякаш сте въвели cmd & в черупка. И така, в кода по-горе вие ​​по същество сте дефинирали условие за състезание - ако вмъкванията могат да завършат навреме, това ще изглежда нормално, но ако не, ще получите неочаквания резултат. Не чакате първия си run() Искате PID да завърши, вие просто връщате неговия Popen екземпляр и продължаване.

Не съм сигурен как това поведение противоречи на документацията, защото има някои много ясни методи на Popen, които изглежда показват, че не се чака, като:

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

Съгласен съм обаче, че документацията за този модул може да бъде подобрена.

За да изчакате програмата да приключи, бих препоръчал да използвате subprocess удобен метод на, subprocess.call , или чрез communicate на Popen обект (за случая, когато имате нужда от stdout). Вече правите това за второто си обаждане.

### 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

Освен това в повечето случаи не е необходимо да изпълнявате командата в обвивка. Това е един от тези случаи, но ще трябва да пренапишете командата си като последователност. Правейки го по този начин също ви позволява да избегнете традиционното инжектиране на черупки и да се тревожите по-малко за цитиране, като така:

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

Това дори ще работи и няма да инжектира, както очаквате:

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

Опитайте интерактивно. Избягвате възможностите за инжектиране на обвивка, особено ако приемате въвеждане от потребителя. Подозирам, че използвате по-малко страхотния метод на низ за комуникация с подпроцес, защото сте се сблъскали с проблеми при насочването на последователностите да работят :^)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mysql подзаявка в LEFT JOIN

  2. Laravel MySql DB връзка със SSH

  3. Как да импортирате повече от 100 000 записа в mysql база данни?

  4. Изберете артикули от различни източници и подредете по дата

  5. филтър за лоши думи, написан в MYSQL без php