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");
}文章来源:https://www.toymoban.com/news/detail-838709.html
} 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;
}
}文章来源地址https://www.toymoban.com/news/detail-838709.html
到了这里,关于android 运行shell 脚本文件或shell命令的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!