+ 6

How to deal with multiple subprocess and read stdout while process running ?

I have one script named "adb_keycode_test.sh", it will input keyevent via adb, then I want to capture logcat(while script running) from device and writing them into a file, the code are listed below: proc_logcat = subprocess.Popen('adb logcat | grep KeyCode', shell=True, stdout=subprocess.PIPE) proc_script = subprocess.check_output(['./adb_keycode_test.sh']) text = proc_logcat.communicate ==> hangs here #text = proc_logcat.stdout.read() ==> hangs too It can run perfectly without "proc_logcat.stdout.read()", my question is how to run "adb_keycode_test.sh" and "adb logcat" simultaneously, and terminate "adb logcat" after keycode script completed ?

17th Apr 2018, 6:25 AM
Corey
Corey - avatar
10 Respostas
+ 2
Kuanlin Chen Short: because stdout is for writing and stdin is for reading Long: Reading from stdout while multithreading will evoke a race condition. AND RACE CONDITIONS ARE EVIL!!
17th Apr 2018, 11:31 AM
Loeschzwerg
+ 5
Loeschzwerg Thanks for clarifying that for Kuanlin Chen. I was just about to sleep when I sent that link and couldn't explain further at the time.
17th Apr 2018, 1:37 PM
David Carroll
David Carroll - avatar
+ 5
Loeschzwerg David Carroll I try to use PIPE like this: from subprocess import Popen, PIPE, STDOUT proc_script = Popen(['./adb_keycode_test.sh'], stdout=PIPE, stdin=PIPE, stderr=STDOUT) text = proc_script.communicate(input='1\n2\n')[0] print(text) I am using python 2.7.6, this solution works for me.
18th Apr 2018, 1:00 AM
Corey
Corey - avatar
+ 5
Loeschzwerg David Carroll But I go one step further, try to get output from proc_logcat: from subprocess import Popen, PIPE, STDOUT cmd = "adb logcat | grep KeyCode" proc_logcat = Popen(cmd.split(' '), stdout=PIPE, stdin=PIPE, stderr=STDOUT) proc_script = Popen(['./adb_keycode_test.sh'], stdout=PIPE, stdin=PIPE, stderr=STDOUT) text = proc_logcat.communicate(input='1\n2\n')[0] ===> Hangs here ! os.kill(proc_logcat.pid, signalSIGTERM) print(text) In my opinion, "adb logcat" will not stop until terminate it by "Ctrl+C", proc_logcat didn't return, so it will not go to the next line, is there any better way to do this ?
18th Apr 2018, 1:11 AM
Corey
Corey - avatar
17th Apr 2018, 6:34 AM
David Carroll
David Carroll - avatar
+ 4
Should have more explain about "pipes" and why do I never read from stdout ?
17th Apr 2018, 9:46 AM
Corey
Corey - avatar
+ 4
Loeschzwerg Thanks!
17th Apr 2018, 2:38 PM
Corey
Corey - avatar
+ 3
@Loeschzwerg What do you mean by "pipes" ?
17th Apr 2018, 7:39 AM
Corey
Corey - avatar
+ 3
Solved: cmd = "adb logcat | grep KeyCode" proc_logcat = subprocess.Popen(cmd.split(' '), stdout=subprocess.PIPE) proc_script = subprocess.check_call(['./adb_keycode_test.sh']) os.kill(proc_logcat.pid, signal.SIGTERM) text = proc_logcat.stdout.read()
17th Apr 2018, 9:28 AM
Corey
Corey - avatar
+ 2
Reading from stdout is really bad coding style. NEVER do that! Use pipes instead.
17th Apr 2018, 6:58 AM
Loeschzwerg