Полное управление терминалом на Android

Я пытался запустить несколько команд Linux на своем телефоне Android с помощью

Process process = Runtime.getRuntime().exec(COMMAND);
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));

И заметил, что я могу запускать только определенные команды и получать правильный результат, даже если устройство рутировано с помощью SuperSU (я также тестировал его с устройством без SuperSU).

Например, если я запускаю ls и пытаюсь вывести его на экран (через TextView) следующим образом:

public void onBtnClick(View view) {
    try {
        EditText commandLine = findViewById(R.id.commandText);
        Process process = Runtime.getRuntime().exec(commandLine.getText().toString());
        BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
        ((TextView) findViewById(R.id.mainTextView)).setText(((TextView) findViewById(R.id.mainTextView)).getText() + "\n" + in.readLine());
        commandLine.setText("");

    } catch (IOException e) {
        e.printStackTrace();
    }
}

вывод acct, что имеет смысл.

Но с другой стороны, если, скажем, я запускаю pwd, это дает мне следующую ошибку:

W/System.err: java.io.IOException: Error running exec(). Command: [pwd] Working Directory: null Environment: null

Я провел некоторое исследование в Интернете и наткнулся на Термукс, который может иметь полный контроль над телефоном через терминал, и это именно то, что я хочу сделать (для моих собственных целей обучения и тестирования).

И хотя это всего лишь эмулятор, он может делать именно то, что я хочу, но единственная проблема в том, что он требует, чтобы я вводил команды через терминал.

Я здесь для того, чтобы как бы воспроизвести то, что Termux делает для меня, чтобы я мог правильно запускать команды Linux из кода Java приложения, не требуя от пользователя фактического ввода команд.

Может ли кто-нибудь помочь мне с чего начать и с основами правильного выполнения этих команд на моем устройстве?

Начиная с Termux с открытым исходным кодом, вы можете посмотреть, как это делает Termux.

CommonsWare 18.01.2019 20:45

Я ожидаю, что вы сталкиваетесь с командами, которые реализуются не программой, а оболочкой. И поскольку вы не используете оболочку, этих команд не существует. Решения заключаются в том, чтобы реализовать их самостоятельно или сначала запустить оболочку и передать через нее команды.

Gabe Sechan 18.01.2019 20:46

Так в чем именно заключается ваш вопрос?

Jafar Akhondali 18.01.2019 20:55

@CommonsWare Ого... как я это пропустил? Спасибо

Ely Shaffir 19.01.2019 13:09
0
4
375
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Termux заявляет, что он не работает как традиционный bash для Linux, поскольку он устанавливает свою собственную виртуальную среду при первой настройке в своем каталоге данных в /data/data/com.termux/files/usr, см. здесь и здесь. Также согласно официальные документы андроида метод exec(command),

Executes the specified string command in a separate process.

This is a convenience method. An invocation of the form exec(command) behaves in exactly the same way as the invocation exec(command, null, null).

Поэтому, если это отдельный процесс, при выполнении команды он будет запускать ее внутри каталога этого процесса (каждый процесс в Linux получает свой каталог и ему назначается PID, который использует ОС). Так что команда ls дает вам просто то, что находится внутри каталога этого процесса. У вас должно быть где-то вроде /proc/31415/ и там только файл acct (cgroup в обычном линуксе).

Что вам нужно сделать, так это запустить команду внутри каталога, объявив ее при вызове getRuntime().exec(), см. ссылку выше, чтобы найти нужную вам команду. Я бы предложил использовать переопределение, которое обрабатывает все параметры. Вам понадобится что-то вроде этого:

String[] cmd = {"mkdir", "testDir"};
File env =  new File(getFilesDir().getAbsolutePath());
Runtime.getRuntime().exec(cmd, null, env);

Кроме того, не помешает взглянуть на код установщика (exec()) Termux. Это даст вам хорошее представление о настройке вашей среды, а также о работе с основными командами.

Кроме того, я думаю, что вы уже сделали это, но еще раз проверьте, запрашиваете ли вы разрешение WRITE_EXTERNAL_STORAGE для своего приложения.

Спасибо! фантастический ответ!

Ely Shaffir 19.01.2019 13:08

@ElyShaffir также следит за тем, чтобы команды, которые вы хотите запустить, могли сильно повредить пользовательское устройство.

shalbafzadeh 20.01.2019 22:17

Другие вопросы по теме