Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to execute Shell scripts from Android application

I've been experimenting with Termux, the Android terminal emulator.

It is an excellent application that allows access to the Android operating system without requiring root access.

What I would like to be able to achieve is execute scripts/commands within Termux from within another Android application installed on the same device.

I believe Termux used to allow Tasker tasks to be executed via intents, however this doesnt appear to be the case now.

Is it possible to execute a script of set of commands via Termux (or any other such app) from another Android application.

or...

Is it possible to access the underlying Android operation system and execute scripts from within an Android app?

UPDATE

When I execute this code from my Android application

    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);
    }

I get this error message

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) 

However com.termux can execute commands like this. How do I get permission to execute these commands in my applicatgion?

like image 202
Hector Avatar asked Jul 13 '19 12:07

Hector


People also ask

Can I run shell script in Android?

Without root you don't have too many choices to run a script from. If you want to run from adb shell , it can be either /sdcard or /data/local/tmp . If you want to run from a terminal emulator app, it can be either /sdcard or app's private directory in /data/data .

How do I run a shell script in Termux?

sh) scripts, you can place them in the . shortcuts directory. A widget can now be placed on your home screen by holding it down, then choosing the Termux:Widget widget. Tapping the script will now automatically open a Termux instance and run it.


1 Answers

So far as I have tried, it works. I think it is supposed to, because that is how many Linux GUI apps do some of their work, by issuing shell commands.

To make sure, I tried issuing a vanilla command's output over to Logcat on an old, low-end, unrooted Android 6.0 phone, and it worked (working code below).

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);
    }
}

However, your mileage might vary wildly here. With so many Android manufacturers, I would expect different versions of the command shell on different devices, and thus I wouldn't expect every Android device to be able to run just any command I threw at it, unless it's a really common one.

Besides, you might also run into problems with system permissions with the commands themselves rather than the command shell (ie. busybox: Permission denied).

like image 74
Leo supports Monica Cellio Avatar answered Oct 04 '22 23:10

Leo supports Monica Cellio