前言:出于某些原因,要对APP沙盒数据进行实时监控。但手动用AK的文件查看器操作太繁琐,于是尝试用脚本来实现自动化监控以提高效率。通过对脚本的优化,倒逼自己不断地学习和总结shell编程知识。
update:2018-09-13 16:07:30
任务描述
- 实时查看安卓手机中
/data/data/当前运行APP的包名/files/
目录中以jar和dex结尾的文件名。
代码
# V0.1
while true;
pkgname=$(dumpsys activity top|grep pid|awk '{print $2}'|awk -F '/' '{print $1}');
do echo -n "#=============Checking $pkgname ";
date;
find /data/data/$pkgname/ -iname \*.jar -o -iname \*.dex;
sleep 1;
done;
由于busybox
为阉割版,对换行后的脚本支持不到位。代码本身没有换行,为了便于观看,这里做了换行处理。
代码解析
- 运行环境
Android底层采用了linux内核,可以执行一些基本的shell命令。安装busybox
后,可以使用一些高级的命令。 - 初始配置
- 上述代码保存为
checknow.sh
- 发送到手机
adb push checknow.sh /data/local/tmp/
- 赋予执行权限
adb shell su -c chmod 0755 /data/local/tmp/checknow.sh
- 执行脚本
adb shell su -c /data/local/tmp/checknow.sh
- 在shell脚本中实现循环
要做到实时监控,必须要有一个循环的逻辑。linux系统中使用watch -n 秒数 命令
可以每隔n秒执行一次指定命令,但在手机中却运行不起来,又是busybox的锅……
顺手学了一下循环指令:
while true;
do xxx;
sleep n; # n是秒数,可以是小数。
done;
- 获取当前运行的app信息
shell@hammerhead:/ $ dumpsys activity top
TASK com.miui.mihome2 id=1
ACTIVITY com.miui.mihome2/com.android.launcher2.Launcher 43045638 pid=1107
Local Activity 427982f0 State:
mResumed=true mStopped=false mFinished=false
mLoadersStarted=true
mChangingConfigurations=false
mCurrentConfig={0.85 460mcc65535mnc zh_CN ldltr sw360dp w360dp h567dp 480dpi nrml port finger -keyb/v/h -nav/h s.38}
FragmentManager misc state:
mActivity=com.android.launcher2.Launcher@427982f0
mContainer=android.app.Activity$1@427a2640
#……
在adb shell
中,通过dumpsys activity top
可以获取手机屏幕上运行的应用信息。但信息太多,接下来可以用一系列的shell命令把APP包名给提取出来。
- 使用grep指令提取目标字符串所在行
shell@hammerhead:/ $ dumpsys activity top|grep pid
ACTIVITY com.miui.mihome2/com.android.launcher2.Launcher 43045638 pid=1107
在上面代码中,|
为管道命令,将结果重定向到grep中。grep 后面跟一个关键词,可以提取出关键词所在的一整行。经过观察发现,pid可以作为该关键词。此外,grep -v 关键词
可以查找不含关键词的行。
- 使用awk提取行中的关键词
shell@hammerhead:/ $ dumpsys activity top|grep pid|awk '{print $2}'
com.miui.mihome2/com.android.launcher2.Launcher
默认情况下,awk会按照空格对行进行分割,分割后可 '{print $数字}'
按照位置顺序输出,从1开始计数。注意,'{print $0}'
代表的是分割前的完整字符串。
接下来用awk -F
对指定字符串/
进行分割,获取到包名com.miui.mihome2
awk支持正则,也许不用多次使用awk分割,以后若掌握了更高级用法会补充进来。
-
使用shell变量
将上述命令获取到的包名赋值给pkgname
,供后续使用:
pkgname=$(dumpsys activity top|grep pid|awk '{print $2}'|awk -F '/' '{print $1}')
变量赋值:变量名=$(一条指令)
,或变量名="字符串"
,注意这里是圆括号。
变量引用:$变量名
,或${变量名}
,注意这里是花括号。
关于shell数组还可以参考这里http://www.runoob.com/linux/linux-shell-array.html -
使用find查找文件
find命令可以递归查找指定文件夹内的文件,基本用法为:find 目录名 -name 文件名
。
网友评论