是否可以从Android应用程序执行Shell脚本

Hec*_*tor 7 bash shell android sh

我一直在尝试使用Android终端模拟器Termux。

这是一个出色的应用程序,无需root访问权限即可访问Android操作系统。

我想要实现的是从安装在同一设备上的另一个Android应用程序中在Termux中执行脚本/命令。

我相信Termux过去曾经允许通过意图执行Tasker任务,但是现在看来情况并非如此。

是否可以通过Termux(或任何其他此类应用程序)从另一个Android应用程序执行命令集的脚本。

要么...

是否可以在Android应用程序中访问底层的Android操作系统并执行脚本?

更新

当我从Android应用程序执行此代码时

    try {
        ProcessBuilder pb = new ProcessBuilder("pkg", "install -y", "ffmpeg python");
        final Process p = pb.start();
        BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        while ((line = br.readLine()) != null) {
            Log.d(TAG, "onCreate(2): " + line);
        }
    } catch (Exception ex) {
        Log.e(TAG, "onCreate: ", ex);
    }
Run Code Online (Sandbox Code Playgroud)

我收到此错误消息

java.io.IOException: Cannot run program "pkg": error=13, Permission denied
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1050)
        at org.home.assignment.shell.MainActivity.commandThree(MainActivity.java:32)
        at org.home.assignment.shell.MainActivity.onCreate(MainActivity.java:21)
        at android.app.Activity.performCreate(Activity.java:7802)
        at android.app.Activity.performCreate(Activity.java:7791)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3243)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3407)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7343)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:933)
     Caused by: java.io.IOException: error=13, Permission denied
        at java.lang.UNIXProcess.forkAndExec(Native Method)
        at java.lang.UNIXProcess.<init>(UNIXProcess.java:133)
        at java.lang.ProcessImpl.start(ProcessImpl.java:141)
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
        at org.home.assignment.shell.MainActivity.commandThree(MainActivity.java:32) 
        at org.home.assignment.shell.MainActivity.onCreate(MainActivity.java:21) 
        at android.app.Activity.performCreate(Activity.java:7802) 
        at android.app.Activity.performCreate(Activity.java:7791) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3243) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3407) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7343) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:933) 
Run Code Online (Sandbox Code Playgroud)

但是com.termux可以执行这样的命令。如何获得在我的应用中执行这些命令的权限?

SE *_*lio 7

据我尝试,它有效。我认为这是应该的,因为这是通过发出 shell 命令来完成某些工作的 Linux GUI 应用程序的数量。

为了确保这一点,我尝试Logcat在旧的、低端的、无根的 Android 6.0 手机上发出一个普通命令的输出,并且它工作正常(下面的工作代码)。

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String[] cmd = new String[]{"ls", "-la", "/"};

        try {
            // These two lines are what we care about
            Process process = Runtime.getRuntime().exec(cmd);
            InputStream iStream = process.getInputStream();

            // This is how we check whether it works
            tryWriteProcessOutput(iStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void tryWriteProcessOutput(InputStream iStream) throws IOException {
            BufferedReader reader = new BufferedReader(new InputStreamReader(iStream));

            String output = "";
            String line;

            try {
                while ((line = reader.readLine()) != null) {
                    output += line + "\n";
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                reader.close();
            }

        Log.d("cmdOutput", output);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,您的里程在这里可能会有很大差异。有这么多 Android 制造商,我希望不同设备上有不同版本的命令外壳,因此我不希望每个 Android 设备都能运行我给它的任何命令,除非它是一个非常常见的命令。

此外,您还可能会遇到命令本身而不是命令外壳(即busybox: Permission denied)的系统权限问题。