android 运行shell 脚本文件或shell命令

android 运行shell 脚本文件或shell命令
一.运行shell脚本文件
1.test.sh文件内容
#!/bin/bash
echo "I am a script"
ps
2.将shell文件拷贝到Android设备目录
3.执行脚本文件 Runtime.getRuntime().exec("sh /sdcard/lilei/test.sh");
注:应用需要有存储访问权限,如果shell文件中有文件访问请用绝对路径,否则访问不到
二.运行shell命令
调用Runtime.getRuntime().exec(String cmdarray[]) ,这里传递命令数组或者Runtime.getRuntime().exec(String command)直接执行命令。

注:有些shell命令可以在 adb shell 中运行,但是通过应用Runtime执行命令会失败(即使当前已经是uid system权限)当前测试系统版本Android11.
例如 adb shell中可以执行执命令:pm install -r -t /data/local/tmp/test-debug.apk 安装应用


但是通过代码运行无法安装:Process p = Runtime.getRuntime().exec("pm install -r -t /data/local/tmp/test-debug.apk");
系统日志会报错01-09 15:35:45.548 18925 18925 W cmd : type=1400 audit(0.0:580): avc: denied { read } for name="test-debug.apk" dev="vdb" ino=1130534 scontext=u:r:system_app:s0 tcontext=u:object_r:shell_data_file:s0 tclass=file permissive=0

缺少什么权限:     { read }权限,
谁缺少权限:        scontext=u:r:system_app:s0 
对哪个文件缺少权限: tcontext=u:object_r:shell_data_file:s0
什么类型的文件:  tclass=file 
完整的意思: scontext=u:r:system_app:s0进程对shell_data_file:s0类型的file缺少read 权限。

可执行adb root后再执行:
setenforce 0 (临时禁用掉SELinux)
getenforce (得到结果为Permissive)
上述命令执行完之后,代码就可以执行安装命令了,基本可以确认是SELinux造成的权限问题,需要通过正规的方式来解决权限问题。

-----------------具体实现如下--------------------------------
/**
* date: 04/23/2020.
* author: lilei.
*/
public class RuntimeUtil {
private static final String TAG = AppConstants.APP_TAG + "RuntimeUtil ";
private static final String SAVE_LOG_DIR_PATH = AppConstants.TSP_DIR + "/log/";

/**
* 测试运行shell 脚本文件
* @return
*/
public static String testRunShell() {
Log.d(TAG, "testRunShell 11");
String cmd = "ps";
try {
java.lang.Process p = Runtime.getRuntime().exec("sh /sdcard/lilei/test.sh");
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
int index = 0;
while ((line = in.readLine()) != null) {
Log.d(TAG, "testRunShell 22 index:"+index +" line:"+line);
index++;
}
} catch (IOException e) {
Log.d(TAG, "testRunShell err=" + e.toString());
}

Log.d(TAG, "testRunShell 33");
return null;
}
/**
* getRetrieveLog from cmd adb logcat.
* for log test.
*
* @param timeMillis timeMillis.
* @param line if line is 0,set recent 5 second time.
*/
public static void getRetrieveLog(long timeMillis, String line) {
String retrieveTime = DateTimeUtil.getBeforeMillisDateTime(timeMillis, 5000);
Log.d(TAG, "getRetrieveLog() begin retrieveTime:" + retrieveTime
+ " line:" + line);
try {
ArrayList<String> cmdLine = new ArrayList<String>();
cmdLine.add("logcat");
cmdLine.add("-t");
if ("0".equals(line)) {
cmdLine.add(retrieveTime);
} else {
cmdLine.add(line);
}
Log.d(TAG, "getRetrieveLog() cmdLine:" + cmdLine.toString());

Process process = Runtime.getRuntime().exec(
cmdLine.toArray(new String[cmdLine.size()]));
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));

String str = null;
while ((str = bufferedReader.readLine()) != null) {
Log.d(TAG, "getRetrieveLog() str:" + str);
}
if (str == null) {
Log.d(TAG, "getRetrieveLog() end!!-- is null --");
}
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* getRetrieveLogToFile from cmd adb logcat.
*
* @param timeMillis current time.
* @param recentSeconds recent seconds.
* @param fileName file name.
* @return Full log path.
*/
public static String getRetrieveLogToFile(long timeMillis, int recentSeconds, String fileName) {
String retrieveTime = DateTimeUtil.getBeforeMillisDateTime(
timeMillis, recentSeconds * 1000);
Log.d(TAG, "getRetrieveLogToFile() begin UTF-8 timeMillis:" + timeMillis
+ " recentSeconds:" + recentSeconds + " begin retrieveTime:" + retrieveTime);
BufferedWriter bufferedWriter = null;
ArrayList<String> cmdLine = new ArrayList<String>();
cmdLine.add("logcat");
cmdLine.add("-t");
cmdLine.add(retrieveTime);

Log.d(TAG, "getRetrieveLog() cmdLine:" + cmdLine.toString());
Process process = null; //capture log.
String fullLogPath = null;
try {
//create a new path.
File dirFile = new File(SAVE_LOG_DIR_PATH);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
process = Runtime.getRuntime().exec(cmdLine.toArray(new String[cmdLine.size()]));

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
process.getInputStream()));

fullLogPath = SAVE_LOG_DIR_PATH + fileName;
bufferedWriter = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(fullLogPath), StandardCharsets.UTF_8));
int len = 0;
byte[] buf = new byte[1024];
String str = null;
while ((str = bufferedReader.readLine()) != null) {
//Start reading the log, one line at a time.
//Log.d(TAG, "getRetrieveLogToFile() str:" + str);
bufferedWriter.write(str + "\r\n");
}

} catch (IOException e1) {
Log.d(TAG, "getRetrieveLogToFile() error:" + e1);
e1.printStackTrace();
} catch (Exception e) {
Log.d(TAG, "getRetrieveLogToFile() error:" + e);
e.printStackTrace();
} finally {
if (null != bufferedWriter) {
try {
bufferedWriter.close();
bufferedWriter = null;
} catch (IOException e) {
Log.e(TAG, "getRetrieveLogToFile() error:" + e);
}
}
}
Log.d(TAG, "getRetrieveLogToFile() end!!");
return fullLogPath;
}
}

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值