#java #bash
Вопрос:
Следующая команда отлично выполняется в bash:
Команда:
bash -c "$(echo 'H4sIAArQ/mAAA1WMuw7CIBRAd77ihLJqtKuTg19hHIjetiQU0svl/1sn43weaeKJD4PnlI2R1w1bpOBA3kvF340ssX1Z1LmvUqyhsvWk8jl7nOQmP/2x9ZixSlXWqnLcYvlrw4VwJYxHOiW3AwCHgS2AAAAA' | base64 --decode | zcat)" - -a -b
Выход:
Equal to or more than 2 arguments - -a -b
Хотел знать — как я могу добиться этого с помощью Java ProcessBuilder?
Я попробовал следующее:
ProcessBuilder processBuilder = new ProcessBuilder(args);
где находятся аргументы:
bash
-c
"$(echo 'H4sIAArQ/mAAA1WMuw7CIBRAd77ihLJqtKuTg19hHIjetiQU0svl/1sn43weaeKJD4PnlI2R1w1bpOBA3kvF340ssX1Z1LmvUqyhsvWk8jl7nOQmP/2x9ZixSlXWqnLcYvlrw4VwJYxHOiW3AwCHgS2AAAAA' | base64 --decode | zcat)"
-
-a
-b
Но я продолжаю получать следующую ошибку:
-: if: command not found
Process finished with exit code 127
Может кто-нибудь, пожалуйста, указать на проблему здесь?
Комментарии:
1. Я подозреваю, что вы берете код, который был создан для оценки внешней оболочкой, а затем используете его в среде, где есть только одна оболочка-внутренняя.
2. Видеть replit.com/@CharlesDuffy2/SmartUniqueAnalysts#Main.java
3. Кстати: одна только ваша сжатая строка base64 длиннее (156 байт), чем сама несжатая программа (124 байта). Почему бы не выполнить несжатую программу напрямую, чтобы обезопасить некоторые ресурсы и избежать проблем?
4. Итак, основная проблема заключается в длинном сценарии (6000 символов). Степень сжатия в этом случае остается 60%. Вышеуказанная проблема предназначена только для представления.
5. Имеет смысл. Спасибо за информацию и за размещение минимального примера вместо полного сценария.
Ответ №1:
Результаты подстановки команд в bash не проходят все этапы синтаксического анализа. Это означает, что составные команды типа if
не выполняются, разделители команд типа ;
не имеют синтаксического значения и т. Д.
Если вы хотите переопределить это и принудительно выполнить дополнительный синтаксический анализ, вам нужно использовать eval
. Таким образом:
args = String[]{
"bash",
"-c",
"eval "$(echo 'H4sIAArQ/mAAA1WMuw7CIBRAd77ihLJqtKuTg19hHIjetiQU0svl/1sn43weaeKJD4PnlI2R1w1bpOBA3kvF340ssX1Z1LmvUqyhsvWk8jl7nOQmP/2x9ZixSlXWqnLcYvlrw4VwJYxHOiW3AwCHgS2AAAAA' | base64 --decode | zcat)"",
"-",
"-a",
"-b",
}
Почему это сработало, когда вы запустили его в оболочке, а не из конструктора процессов? Потому что оболочка , в которой вы ее запустили, выполнит подстановку команд "$(...)"
и поместит результаты этой подстановки в текст, который она передала дочерней оболочке; таким образом, подстановка уже была выполнена во время синтаксического анализа.
Комментарии:
1. Спасибо за замечательное объяснение! Работает ли это так же и для аргументов? Допустим, вместо
"-b"
«Я хочу сдать"eval "$(echo 'H4sIALLp/mAAA9NN4gIAmuzKeAMAAAA=' | base64 --decode | zcat)""
«?2. Только аргумент сразу после
-c
этого анализируется как код. Все остальные сохраняют свои буквальные значения. Это важно с точки зрения безопасности-в противном случае никогда нельзя было бы написать сценарий bash, способный безопасно обрабатывать ненадежные данные.3. Спасибо за разъяснение.