Как запускать команды суперпользователя в Linux через код Java?
В моем приложении несколько пользователей и 1 суперпользователь. Я пытаюсь написать и сохранить файл в Linux через код Java, но я получаю сообщение об ошибке "Отказано в разрешении". Я использовал следующий код:
Process process = Runtime.getRuntime().exec("/usr/bin/tiff2pdf -o /tmp/tiff_dir/temp.pdf /tmp/tiff_dir/image.tiff");
int returnCode = process.waitFor();
Я получаю следующую ошибку:
java.io.FileNotFoundException: image.tiff (Permission denied)
Из моего анализа кажется, что, поскольку у пользователя нет прав root, я получаю эту ошибку. Какое решение для этого?
3 ответа
Вы не должны запускать такую команду как суперпользователь, потому что это представляет угрозу безопасности (то есть, если кто-то получил контроль над вашей Java-программой, у него есть ключи от королевства). Вместо этого вы должны работать с более низкими разрешениями.
Похоже, проблема с доступом к image.tiff
не с tiff2pdf
, Проверьте владельца и разрешения image.tiff
,
Во-первых, эти две линии не будут производить java.io.FileNotFoundException: image.tiff (Permission denied)
:
Process process = Runtime.getRuntime().exec("/usr/bin/tiff2pdf -o temp.pdf image.tiff");
int returnCode = process.waitFor();
Если по какой-либо причине команда не выполнится, она вернет ненулевой код возврата, что приведет к некоторому выводу стандартной ошибки процесса (это соглашение). Вы можете получить эту стандартную ошибку от process.getErrorStream()
(может быть, стоит взглянуть на стандартный вывод тоже, на всякий случай). Если есть проблема с файлом, который там не найден, он не выдаст FileNotFoundException
как это, так как Java не может понять ожидаемый результат от вашей команды.
РЕДАКТИРОВАТЬ, следуя вашему комментарию:
Он был выдан только с этой точки, и значение returnCode было 1. Также все работало нормально, как только я вручную изменил права доступа к файлам от пользователя root.
Это просто невозможно. Если ваше приложение выдает исключение в любую из этих двух строк, оно выйдет из нормального потока управления: вы не сможете прочитать returnCode
совсем.
Во-вторых, ваш должен запустить ваш exec
Команда с каждым аргументом в String[]
вместо того, чтобы все это было в одной строке, это должно предотвратить проблемы с кавычками, если имена файлов имеют пробелы, например.
Я бы также предложил использовать абсолютные пути в вашей команде, чтобы убедиться, что вы работаете в каталогах, которые вы ожидаете. (* РЕДАКТИРОВАТЬ: * Теперь, когда вы используете абсолютные пути, убедитесь, что у вашего пользователя есть разрешения rwx на /tmp/tiff_dir
.)
Чтобы ответить на ваш вопрос более прямо, вы можете запустить sudo
с Runtime.exec(new String[] {"/usr/bin/sudo", ... the rest of your command ... }
но это плохая идея по соображениям безопасности. Вам также необходимо изменить sudoers
файл, чтобы разрешить его без пароля, или найти способ передать пароль, либо в командной строке (определенно, для угрозы безопасности!), либо путем передачи его во входной поток вручную, каким-либо образом.)
Попробуй это:
File file = new File("/opt/image.tiff");
Runtime runtime = Runtime.getRuntime();
runtime.exec(new String[] { "/bin/chmod", "777",file.getPath()});
Это выполнит полное разрешение для файла.