Автоматически вводить ввод в командной строке


143

Я запускаю сценарий, который запрашивает ввод 'y' для каждой операции, я ищу решение, как $ ./script < echo 'yyyyyyyyyyyyyy'передать все мои данные за один раз.


Иногда -fопция работает хорошо с определенными командами.
iammilind

Ответы:


259

Существует команда, созданная специально для этого случая: yes

$ yes | ./script

Для этого нужно подключить выход yesк входу ./script. Поэтому, когда ./scriptпользователь запрашивает ввод, он вместо этого получает вывод yes. Результатом yesявляется бесконечный поток, за yкоторым следует символ новой строки. Так что в основном, как будто пользователь вводит yдля каждого вопроса ./script.

Если вы хотите сказать нет ( n) вместо да ( y), вы можете сделать это так:

$ yes n | ./script

Обратите внимание, что некоторые инструменты имеют возможность всегда принимать yesответ. См. Здесь, например: Обойти приглашение yes / no в 'apt-get upgrade'


Другие способы ввода ввода:

Если вы точно знаете, сколько yожидает ваш скрипт, вы можете сделать это так:

$ printf 'y\ny\ny\n' | ./script

Новые строки ( \n) - это клавиши ввода.

Используя printfвместо yesвас более точный контроль ввода:

$ printf 'yes\nno\nmaybe\n' | ./script

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

$ printf 'yyy' | ./script

Для полноты вы также можете использовать здесь документ :

$ ./script << EOF
y
y
y
EOF

Или, если ваша оболочка поддерживает строку здесь :

$ ./script <<< "y
y
y
"

Или вы можете создать файл с одним вводом на строку:

$ ./script < inputfile

Если команда достаточно сложна и вышеописанных методов уже недостаточно, вы можете использовать функцию ожидаемо .

Вот пример очень простого сценария ожидания:

spawn ./script
expect "are you sure?"
send "yes\r"
expect "are you really sure?"
send "YES!\r"
expect eof

Технический придира:

Гипотетический вызов команды, который вы дали в своем вопросе, не работает:

$ ./script < echo 'yyyyyyyyyyyyyy'
bash: echo: No such file or directory

Это потому, что грамматика оболочки позволяет оператору перенаправления в любом месте командной строки. Что касается оболочки, ваша гипотетическая командная строка такая же, как эта:

$ ./script 'yyyyyyyyyyyyyy' < echo
bash: echo: No such file or directory

Это означает, ./scriptчто будет вызван с аргументом, 'yyyyyyyyyyyyyy'а стандартный ввод получит данные из файла с именем echo. И Баш жалуется, так как файл не существует.


1
Я получаю cannot enable tty mode on non tty input. Знаете ли вы, как обойти это?
bmpasini

Когда я пытаюсь printfпроделать трюк с runфайлом, который мне нужен для автоматизации процесса установки, все, что происходит, это то, что я получаю сообщение об ошибке Warning: Tried to connect to session manager, None of the authentication protocols specified are supported, и скрипт открывается в новом терминале и просит меня ввести свой ввод вручную, как обычно. Кстати, это происходит в Debian. Какие-либо предложения?
DavidB

нужно больше деталей. слишком большой для комментариев. пожалуйста, задайте новый вопрос со всеми деталями. Вы можете поставить ссылку здесь.
лесмена

ничто не работает с 'vagrant destroy' на centos
Дрю

Злой легко! Работает над импортом данных Google Cloud Beta SQL! Очень признателен!
G_Style

11

Используйте команду yes:

yes | script

Выдержка из справочной страницы:

NAME
       yes - output a string repeatedly until killed

SYNOPSIS
       yes [STRING]...
       yes OPTION

DESCRIPTION
       Repeatedly output a line with all specified STRING(s), or 'y'.

9

Некоторые вещи ( apt-getнапример) принимают специальные флаги для запуска в тихом режиме (и принимают значения по умолчанию). В apt-getслучае, вы просто передаете ему -yфлаг. Это полностью зависит от вашего сценария, хотя.

Если вам нужны более сложные вещи, вы можете обернуть ваш сценарий в ожидаемый сценарий. Ожидаемый позволяет вам читать вывод и отправлять ввод, так что вы можете делать довольно сложные вещи, которые не позволят другие сценарии. Вот один из примеров со страницы в Википедии :

# Assume $remote_server, $my_user_id, $my_password, and $my_command were read in earlier
# in the script.
# Open a telnet session to a remote server, and wait for a username prompt.
spawn telnet $remote_server
expect "username:"
# Send the username, and then wait for a password prompt.
send "$my_user_id\r"
expect "password:"
# Send the password, and then wait for a shell prompt.
send "$my_password\r"
expect "%"
# Send the prebuilt command, and then wait for another shell prompt.
send "$my_command\r"
expect "%"
# Capture the results of the command into a variable. This can be displayed, or written to disk.
set results $expect_out(buffer)
# Exit the telnet session, and wait for a special end-of-file character.
send "exit\r"
expect eof

Это нельзя использовать со .shсценарием оболочки, верно? Или есть способ?
Шаян

7

В сценарии оболочки вы также можете использовать следующий прием spawn, ожидайте и отправляйте

spawn script.sh
expect "Are you sure you want to continue connecting (yes/no)?"
send "yes"

Однако в приведенном выше сценарии вам нужно будет указать фразу, которую вы ожидаете получить при выполнении сценария, для получения дополнительных примеров перейдите по следующей ссылке

Ожидать в Баш


2

Ладно, это может быть не очень элегантное решение, но если вы напишите свои опции в отдельном файле, а затем передадите их в качестве входных данных для скрипта, это также сработает. Поэтому, если вы создаете новый файл со всеми вашими опциями (назовите этот файл «options.in»), вы можете легко запустить свой скрипт ./script.sh < options.inи отредактировать / создать различные файлы опций по своему усмотрению.


Как мне написать options.inфайл? Можете привести пример?
Шаян

0

Я писал сценарий bash с Dialog, и мне нужно, чтобы это также происходило автоматически. Я сделал это, и это сработало как шарм.

# -Wy force signaturewipe (if exists)
echo "y" | sudo lvcreate -W y -n $lvName -L "$lvSize"G /dev/"$svg" >> $nfsUtilLog

-1

Вы можете вводить пользовательский ввод в ваш скрипт catиз текстового файла, переданного в ваш скрипт bashследующим образом:

cat input.txt | bash your_script.sh

Просто поместите желаемый пользовательский ввод в ваш файл input.txt, независимо от того, какие ответы вы хотите - y, n, цифры, строки и т. Д.



@muru Для меня упомянутое вами решение не сработало, поэтому я должен придумать свое.
WebComer

Навряд ли. Вы оба описываете одно и то же.
Муру,

@muru Подобно идее предоставления ответов из файла (что можно сделать несколькими способами), это не одно и то же, и, кроме того, оно достигнуто совершенно другим способом. Вы должны быть в состоянии увидеть это. Если решение, на которое вы указываете, сработает для меня, я не буду тратить свое время на изобретение колеса сегодня. Вы можете использовать любую работу для вас.
WebComer

@muru Я полагаю, что есть разница между этими двумя понятиями, некоторые из которых описаны в ответах, которые можно найти здесь: askubuntu.com/questions/172982/… . Для меня, например, мой код, если вывод перенаправлен в файл, кажется более четким, как естественный поток слева направо. В конце концов, отказ от работоспособных решений, подобных вам, не стимулирует людей делиться своими решениями здесь. Я считаю, что сказанного достаточно, чтобы убрать отрицательное голосование.
WebComer
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.