I have checked out numerous other threads with the same issue, but cannot get one that works for me.
I am trying to run a command using the | character on a Windows machine, with python and wx.python. Command I'm trying to run is: adb.exe logcat | findstr myApp (stored in pkgName)
I have tried the following with no success, nothing is written in 'progressBox': note: they weren't all tried at the same time ;)
logcat = subprocess.Popen(toolsDir + "\\adb.exe logcat", stdout=subprocess.PIPE)
findstr = subprocess.Popen("findstr '"+ pkgName+"'", stdin=logcat.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = findstr.communicate()
cmd = toolsDir+"\\adb.exe logcat | findstr " + pkgName
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
stdout = ps.communicate()[0]
c_arg = 'logcat | findstr ' + pkgName
params = toolsDir + "\\adb.exe " + c_arg
p = Popen(params, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
They are all slightly different, but none append to my progressBox to print out the output.
self.progressBox.AppendText(stdout)
self.progressBox.AppendText(stderr)
I have myself faced issue numerous times using subprocess library to run system command. I would probably recommend using core os library, still i am not very sure if this will work on windows but you could give a try.
import os
cmd = "ls -la > output.txt"
os.system(cmd)
reader = open("output.txt")
print(reader.read())
PS: It is recommended to use subprocess module to run system command, you should use above code only when you are unable to find a solution and just want to run code urgently.
Related
I am trying to connect two devices to my pc and run some commands on them using python and adb.
when I run the command from the command prompt, it goes through fine, but when i put those in the python script, they give me errors.
this is causing the errors all the time:
from subprocess import check_output, CalledProcessError
try:
adb_ouput = check_output(["adb","devices","-l","|", "grep", "\"model\""])
print adb_ouput
except CalledProcessError as e:
print e
The error message I get is this:
Usage: adb devices [-l]
Command '['adb', 'devices', '-l', '|', 'grep', '"model"']' returned non-zero exit status 1
When I try the same code without the grep command, it works
adb_ouput = check_output(["adb","devices","-l"])
It gives me the right output.
When I try the same in windows command prompt, It works fine (I am replacing grep with FINDSTR because i'm using it in windows, and I have tried doing the same in the python script as well, with 'shell = True' and also without.)
eg:
adb devices -l | FINDSTR "model"
This gives me an ouptut without any problems.
The output I get is
123ab6ef device product:xxxxxxxxx model:xxxxxxxxx device:xxxxxxxxx
bd00051a4 device product:yyyyyyyyyy model:yyyyyyyyyy device:yyyyyyyyy
I am trying to understand where I am going wrong here, but can't figure it out.
So far I have checked the docs: https://docs.python.org/3/library/subprocess.html
https://docs.python.org/3/library/subprocess.html#subprocess.CalledProcessError
These just give me the error codes.
I have also looked at these answers:
Python, adb and shell execution query
I took some error checking from here and added to my code.
Python subprocess.check_output(args) fails, while args executed via Windows command line work OK
python check_output fails with exit status 1 but Popen works for same command
I think i am close but just can't put my finger on it.
Any help would be appreciated.
First
adb_ouput = check_output(["adb","devices","-l","|", "grep", "\"model\""])
certainly requires shell=True, but even with that it's not equivalent to
adb devices -l | FINDSTR "model"
When using check_output, you're passing "model" as grep argument literally but you should pass just model. "model" is not in your output (with quotes) so grep fails to find it, and returns exitcode 1 which is not really an error for grep but makes check_output trigger an exception because it expects 0.
So I would to this as a quickfix:
adb_ouput = check_output(["adb","devices","-l","|", "grep", "model"],shell=True)
And as a longfix I'd perform the grep command directly with python.
adb_output = check_output(["adb","devices","-l"])
for l in adb_output.splitlines():
if "model" in l:
print(l)
I am trying to execute the following command;
String cmd = "/system/bin/netstat -"+firstString+" | grep http";
Process process = Runtime.getRuntime().exec(cmd);
Log.d("1:CMD VALUE", cmd);
The log result is 1:CMD VALUE: /system/bin/netstat -a | grep http
However, the output is not getting filtered for the 'http' parameter. The regular "/system/bin/netstat -a" result is what I get for the "/system/bin/netstat -a | grep http`" command as well. Why is this? Is this because of the pipe symbol or the grep command?
Please help.
Thanks.
Other answers on this website were not very clear. Here is the solution.
You need to append "/system/bin/sh -c" before your runtime command for grep to work.
Cheers.
I am trying to execute adb shell commands in python using subprocess.Popen
Example: Need to execute 'command' in adb shell. While executing manually, I open the command window and execute as below and it works.
>adb shell
#<command>
In Python I am using as below but the process is stuck and doesn't give output
subprocess.Popen('adb shell <command>)
Tried executing manually in command window, same result as python code,stuck and doesn't give output
>adb shell <command>
I am trying to execute a binary file in background(using binary file name followed by &) in the command.
Found a way to do it using communicate() method in subprocess module
procId = subprocess.Popen('adb shell', stdin = subprocess.PIPE)
procId.communicate('command1\ncommand2\nexit\n')
use pexpect (https://pexpect.readthedocs.io/en/stable/)
adb="/Users/lishaokai/Library/Android/sdk/platform-tools/adb"
import pexpect
import sys, os
child = pexpect.spawn(adb + " shell")
child.logfile_send = sys.stdout
while True:
index = child.expect(["$","#",pexpect.TIMEOUT])
print index
child.sendline("ls /storage/emulated/0/")
index = child.expect(["huoshan","google",pexpect.TIMEOUT])
print index, child.before, child.after
break
Ankur Kabra, try the code below:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import subprocess
command = 'adb devices'
p = subprocess.Popen(command, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
print 'standard output: %s \n error output: %s \n',(stdout,stderr)
and you will see the error output.
Usually it will tell you:
/bin/sh: adb: command not found
which means, shell can not excute adb command.
so, adding adb to your PATH or writing the full path of adb will solve the problem.
May help.
When using 'adb pull ...' the output is sent to stderr regardless of success. Is there any reason for this? For an example, pulling a file that is there and pulling a file that doesn't exist:
When I run:
adb pull /data/data/good_file.txt /tmp`
I get the following:
stdout:
stderr: 0 KB/s (13 bytes in 0.078s)
(i.e. no stdout)
Then when when I run:
adb pull /data/data/bad_file.txt /tmp
I get the following:
stdout:
stderr: remote object '/data/bad_file.txt' does not exist
The program below was used to generate the above results:
from subprocess import Popen
cmd = "adb pull /data/data/good_file.txt /tmp"
p = Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
print cmd
print "stdout: " + out
print "stderr: " + err
I have the same issue with: adb install -r /foo/bar.apk and sound like adb always send his result to stderr, just add 2>&1 at end and it solves the problem.
cmd = "adb pull /data/data/good_file.txt /tmp 2>&1"
The 2>&1 just redirects Channel 2 (Standard Error) and Channel 1
(Standard Output) to the same place which in this context is Channel 1
(Standard Output), and thence your log file.
I'm trying to automate the full CTS setup and execution with python & monkeyrunner on Ubuntu and most of it has gone very well. As the very final step, I try executing the following python command to start the CTS on a specific device:
cts_tradefed_script = "./android-cts/tools/cts-tradefed"
process = subprocess.Popen([cts_tradefed_script, "run", "cts", "-s", '"' + serialno + '"', "--plan", "CTS"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
which is the equivalent of:
./android-cts/tools/cts-tradefed run cts -s "R32CB054TSZ" --plan CTS
in the command-line and I get:
Android CTS 4.2_r4
No commands for non-interactive mode; exiting.
06-17 17:32:32 I/: Detected new device R32CB054TSZ
Saved log to /tmp/tradefed_global_log_9173619073367947049.txt
06-17 17:32:32 I/CommandScheduler: All done
The CTS tests don't execute. Is there a command I'm forgetting or is this not possible using Python?
cts_tradefed_script = "./android-cts/tools/cts-tradefed"
process = subprocess.Popen([cts_tradefed_script + " " + serialno], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
Edit: script was not necessary. Just enter everything as a concatenated String.
The problem with non-interactive is that you cannot run more than a command, so you should try to run in interactive mode.
To run in interactive mode this is one way:
#pip install paramiko
import paramiko
import time
def run_remote_command(channel, command):
channel.send(command)
whole_output = ""
while True:
if channel.recv_ready():
output = channel.recv(1024)
whole_output+=output
else:
time.sleep(0.5)
if not(channel.recv_ready()):
return whole_output
server ="fill you own here"
username = "fill you own here"
password = "fill you own here"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(server, 22 ,username, password)
channel =ssh.get_transport().open_session()
channel.get_pty()
channel.invoke_shell()
run_1 =run_remote_command(channel,"~/android/out/host/linux-x86/cts/android-cts/tools/cts-tradefed list devices" + "\n")
print run_1
run_2 =run_remote_command(channel,"run cts" + "\n")
print run_2
run_3 =run_remote_command(channel,"l i" + "\n")
print run_3