web-dev-qa-db-fra.com

Est-il possible d'exécuter des scripts Shell depuis Android

J'ai expérimenté avec Termux, l'émulateur de terminal Android.

C'est une excellente application qui permet d'accéder au système d'exploitation Android sans avoir besoin d'un accès root).

Ce que j'aimerais pouvoir réaliser, c'est exécuter des scripts/commandes dans Termux à partir d'une autre Android installée sur le même appareil).

Je crois que Termux permettait aux tâches Tasker d'être exécutées via des intentions, mais cela ne semble pas être le cas maintenant.

Est-il possible d'exécuter un script d'ensemble de commandes via Termux (ou toute autre application de ce type) à partir d'une autre application Android.

ou...

Est-il possible d'accéder au système d'exploitation sous-jacent Android et d'exécuter des scripts à partir d'une application Android?

METTRE À JOUR

Lorsque j'exécute ce code à partir de mon 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);
    }

Je reçois ce message d'erreur

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) 

Cependant com.termux peut exécuter des commandes comme celle-ci. Comment obtenir la permission d'exécuter ces commandes dans mon application?

8
Hector

Pour autant que j'ai essayé, cela fonctionne. Je pense que c'est censé le faire, car c'est le nombre d'applications Linux GUI qui font une partie de leur travail, en émettant des commandes Shell.

Pour m'assurer, j'ai essayé d'émettre la sortie d'une commande Vanilla sur Logcat sur un ancien téléphone bas de gamme non racine Android 6.0 téléphone, et cela a fonctionné (code de travail ci-dessous).

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

Cependant, votre kilométrage peut varier énormément ici. Avec autant de fabricants Android Android, je m'attendrais à différentes versions de la commande Shell sur différents appareils, et donc je ne m'attendrais pas à ce que chaque Android appareil soit capable pour exécuter n'importe quelle commande que je lui ai lancée, à moins qu'elle ne soit vraiment courante.

En outre, vous pouvez également rencontrer des problèmes avec les autorisations système avec les commandes elles-mêmes plutôt qu'avec la commande Shell (par exemple. busybox: Permission denied).

Termux est un émulateur de terminal mais n'a pas accès à tout dans le système d'exploitation Android. Finalement, c'est une application et fera face à des restrictions comme toute autre application dans Android. APT , pkg et d'autres programmes d'installation ou packages sont installés dans l'émulateur mais pas à l'échelle du système. Certaines commandes auront également des restrictions similaires à votre cas, par exemple pm ne peut être exécuté qu'avec root ou un adb Shell puisque leurs ID utilisateur sont autorisés à effectuer de telles actions alors que d'autres applications ne le sont pas. Signification de l'exécution de la commande pm install -r -t someapp.apk donnera une erreur dans Termux alors que cela fonctionnerait certainement si vous utilisez adb Shell ou disposant de droits root.

Pour rendre les choses encore plus claires, exécutez la commande echo $PATH dans Termux affichera les répertoires dont les commandes Termux sont uniquement incluses, et ce ne sont pas des commandes Android OS mais des packages compilés qui peuvent s'exécuter sur Android OS. Il est une bonne façon de faire tourner les choses sur le dessus Android sans avoir à faire face à beaucoup de restrictions, plus comme un environnement en bac à sable. L'installation de certains paquets qui doivent sortir du bac à sable faire face à des problèmes alors soyez conscient de cela.

2
ahasbini