Вопрос или проблема
В Python есть удобная функция в составе pwntools
, где можно использовать sendline()
для отправки данных исполняемому файлу. Как мне эмулировать эту функциональность в bash?
Пример
#whatever.py
x = input("First input please: ")
y = input("Second input please: ")
Я знаю, что можно использовать echo "input1" | python3 whatever.py
для ответа на первый запрос, но я не могу сделать это в несколько строк (echo "input1\ninput2" | ...
не работает, и также echo "input1"; echo "input2" | ...
не работает).
Ваш Python-скрипт требует две строки ввода через стандартный поток ввода. Любой из следующих способов предоставит это:
-
Два вызова
echo
в подшелле:( echo 'line 1'; echo 'line 1' ) | python3 whatever.py
-
Два вызова
echo
в составной команде:{ echo 'line 1'; echo 'line 1'; } | python3 whatever.py
-
Один вызов
echo
с использованием нестандартной опции-e
для интерпретации встроенного\n
как литерального символа новой строки:echo -e 'line 1\nline 2' | python3 whatever.py
-
Один вызов
printf
, форматирующий каждый последующий аргумент как отдельную строку вывода. Это было бы более подходящее решение для переменных данных, чем использованиеecho
, см. Почему printf лучше, чем echo?.printf '%s\n' 'line 1' 'line 2' | python3 whatever.py
-
Использование перенаправления here-document:
python3 whatever.py <<'END_INPUT' line 1 line 2 END_INPUT
Ответ или решение
Чтобы отправить несколько строк ввода в исполняемый файл с использованием Bash, можно задействовать несколько подходов. Эти методы позволяют передать данные в стандартный поток ввода программы, которая ожидает несколько строк ввода, что характерно для многих сценариев работы с интерактивными консольными приложениями, такими как Python-скрипты или другие исполняемые файлы.
Теория
Для передачи нескольких строк данных, можно использовать разнообразные утилиты Bash, такие как echo
, printf
и конструкции, такие как подстановочные встраивания, компаунд-команды или здесь-документы. Одна из причин, почему echo "input1\ninput2"
не срабатывает, заключается в том, что не все реализации echo
по умолчанию интерпретируют \n
как символ новой строки. Хотя pwntools
в Python предоставляет функциональность для отправки отдельных строк с sendline()
, в мире Bash у нас есть свои инструменты для достижения аналогичного результата.
Пример
Рассмотрим различные варианты передачи нескольких строк в Python-скрипт:
-
Использование подшела:
( echo 'line 1'; echo 'line 2' ) | python3 whatever.py
В данном примере создан подшел, который передает на стандартный поток вывода несколько вызовов
echo
. -
Компаунд-команда:
{ echo 'line 1'; echo 'line 2'; } | python3 whatever.py
Используется набор команд, выполняемых в одной линии, позволяющих отправлять несколько строк ввода в вашу программу.
-
Использование флага
-e
уecho
:echo -e 'line 1\nline 2' | python3 whatever.py
-
printf
— более предпочтительный подход:printf '%s\n' 'line 1' 'line 2' | python3 whatever.py
printf
предпочтителен для создания многострочных строк, особенно если речь идет о переменных данных. -
Здесь-документ:
python3 whatever.py <<'END_INPUT' line 1 line 2 END_INPUT
Здесь-документ позволяет напрямую писать несколько строк текста, который затем передается как ввод программе.
Применение
Выбор метода зависит от специфики вашей задачи. Например, если у вас статические строки, легко использовать обычный echo
или { echo; }
; если же строки ввода формируются динамически — лучше воспользоваться printf
. Если важна читаемость кода и передача больших текстовых блоков, здесь-документы станут наиболее удобным решением.
Таким образом, каждый из методов имеет свои преимущества и позволяет достичь требуемой функциональности, необходимой для отправки многострочного ввода программам в Bash. Выбор подхода должен основываться на конкретной задаче и специфике вводимых данных.