Send data back to the script which started the act

2019-01-05 05:30发布

I want to install a diagnostic app from adb and get back data from it from within a bash script. I know how to start an activity from adb, but I can't find any way to get data back unless maybe if I print to logcat and parse the output, but that sounds like a hack. Is there a way to receive data back from an activity started using adb?

标签: android bash adb
2条回答
可以哭但决不认输i
2楼-- · 2019-01-05 05:40

There is a little In/Out sample:

1st preparation:

tmpfile=$(mktemp /tmp/adb-XXXXXXXXX)
exec 5> >(adb shell >$tmpfile)
exec 6<$tmpfile 
rm $tmpfile

Then you could write to &5 and read from &6:

read -t .1 -u 6 foo;echo $foo
shell@HWY625-U:/ $
read -t .1 -u 6 foo;echo $foo

echo date >&5
read -t .1 -u 6 foo;echo $foo
date
read -t .1 -u 6 foo;echo $foo
Sat Dec 17 18:20:35 CET 2016

Nota: I rm $tmpfile for security reason, but while descriptors stay open, you could use them (timeout option of read work just fine with while loop):

>&5 echo uptime
while read -t .1 -u 6 foo;do echo $foo;done
uptime
up time: 08:16:42, idle time: 01:20:19, sleep time: 06:47:13

And

ls -l $tmpfile
ls: cannot access /tmp/adb-hbmJrFVX4: No such file or directory

ls -l /proc/self/fd
total 0
lrwx------ 1 user user 64 Dec 17 18:24 0 -> /dev/pts/8
l-wx------ 1 user user 64 Dec 17 18:24 1 -> pipe:[22316547]
lrwx------ 1 user user 64 Dec 17 18:24 2 -> /dev/pts/8
l-wx------ 1 user user 64 Dec 17 18:24 5 -> pipe:[22316558]
lr-x------ 1 user user 64 Dec 17 18:24 6 -> /tmp/adb-hbmJrFVX4 (deleted)

When finished, close everything:

>&5 echo exit  
while read -t .1 -u 6 foo;do echo $foo;done
exit
exec 5>&-                                          
exec 6<&-
查看更多
Anthone
3楼-- · 2019-01-05 06:00

If the data that you want to send back to your automation script could be serialized into a string less than 4k long - using logcat is a natural choice. Just make your activity to print the data to the log with Log.i("UNIQUE_TAG", the_data_string_you_want_to_send_back_to_your_script); and then use the following commands in your automation script to capture the output:

# clear the logcat buffer
adb logcat -c

# start your activity
adb shell am start <INTENT>

# this line will block until a string with "UNIQUE_TAG" tag and "Info" priority
# is printed to the main log
adb shell 'logcat -b main -v raw -s UNIQUE_TAG:I | (read -n 1 && kill -2 $((BASHPID-1)))'

# now you can capture the data and process it
DATA=$(adb logcat -d -b main -v raw -s UNIQUE_TAG:I)

In more recent Android versions (7.0+) where logcat properly supports -m <count>, -t <time> and -T <time> parameters you can use this much simpler version without having to clear the log with logcat -c first:

# instead of clearing the log just get the current timestamp
TS=$(adb shell 'echo $EPOCHREALTIME; log ""')

# start your activity
adb shell am start <INTENT>

# this command will return immediately if the data has been printed already or block if not
DATA=$(adb shell "logcat -b main -T $TS -m 1 -v raw -s UNIQUE_TAG:I")
查看更多
登录 后发表回答