Как передать местоположение файла (которое принадлежит другому пользователю) в качестве аргумента для скрипта bash из java-кода [duplicate]

Я исследовал это на пару дней и получил решение. Теперь в Android O вы можете установить ограничение фона как ниже

Служба, вызывающая класс обслуживания

Intent serviceIntent = new Intent(SettingActivity.this,DetectedService.class);
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){

                        SettingActivity.this.startForegroundService(serviceIntent);
                    }else{
                        startService(serviceIntent);
                    }

и класс обслуживания, должна быть как

public class DetectedService extends Service { 
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        int NOTIFICATION_ID = (int) (System.currentTimeMillis()%10000);
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForeground(NOTIFICATION_ID, new Notification.Builder(this).build());
        }


        // Do whatever you want to do here
    }
}
26
задан that other guy 2 August 2015 в 21:00
поделиться

1 ответ

Почему некоторые команды терпят неудачу?

Это происходит потому, что команда, переданная в Runtime.exec(String), не выполняется в оболочке. Оболочка выполняет множество общих служб поддержки для программ, и когда оболочка не собирается их выполнять, команда будет терпеть неудачу.

Когда команды не работают?

Команда будет если это зависит от свойств оболочки. Оболочка имеет много общих и полезных вещей, о которых мы обычно не думаем:

  1. Оболочка правильно раскладывается на кавычки и пробелы. Это удостоверяет, что имя файла в "My File.txt" остается единственным аргументом. Runtime.exec(String) наивно разбивается на пробелы и передает это как два отдельных имени файла. Это явно не получается.
  2. Оболочка расширяет globs / wildcards. Когда вы запускаете ls *.doc, оболочка перезаписывает ее в ls letter.doc notes.doc. Runtime.exec(String) нет, он просто передает их в качестве аргументов. ls не знает, что *, поэтому команда не работает.
  3. Среда управляет трубами и перенаправлением. Когда вы запускаете ls mydir > output.txt, оболочка открывает «output.txt» для вывода команды и удаляет ее из командной строки, предоставляя ls mydir. Runtime.exec(String) нет. Он просто передает их в качестве аргументов. ls не знает, что означает >, поэтому команда не работает.
  4. Оболочка расширяет переменные и команды. Когда вы запускаете ls "$HOME" или ls "$(pwd)", оболочка перезаписывает его на ls /home/myuser. Runtime.exec(String) нет, он просто передает их в качестве аргументов. ls не знает, что означает $, поэтому команда не работает.

Что вы можете сделать вместо этого?

Существует два способа выполнения произвольно сложных команд :

Простая и неаккуратная: делегировать оболочку.

Вы можете просто использовать Runtime.exec(String[]) (обратите внимание на параметр массива) и передать команду непосредственно оболочке, которая может выполнять весь тяжелый подъем:

// Simple, sloppy fix. May have security and robustness implications
String myFile = "some filename.txt";
String myCommand = "cp -R '" + myFile + "' $HOME 2> errorlog";
Runtime.getRuntime().exec(new String[] { "bash", "-c", myCommand });

Безопасный и надежный: возьмите на себя ответственность оболочки.

Это не исправление, которое можно механически применить, но требует понимания модели исполнения Unix, каких оболочек и как вы можете сделать то же самое. Тем не менее, вы можете получить надежное, надежное и надежное решение, сняв оболочку с рисунка. Этому способствует ProcessBuilder.

Команда из предыдущего примера, которая требует, чтобы кто-то обрабатывал 1. кавычки, 2. переменные и 3. перенаправления, может быть записан как:

String myFile = "some filename.txt";
ProcessBuilder builder = new ProcessBuilder(
    "cp", "-R", myFile,        // We handle word splitting
       System.getenv("HOME")); // We handle variables
builder.redirectError(         // We set up redirections
    ProcessBuilder.Redirect.to(new File("errorlog")));
builder.start();
54
ответ дан 2 revs 18 August 2018 в 10:55
поделиться
  • 1
    Один из лучших ответов, которые я когда-либо видел ... Спасибо человеку – Vishnu 20 April 2018 в 05:14
Другие вопросы по тегам:

Похожие вопросы: