Автоматично вводити введення в командному рядку


141

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


Іноді -fваріант добре працює з певними командами.
iammilind

Відповіді:


257

Існує команда, створена спеціально для цього випадку: yes

$ yes | ./script

Для цього потрібно підключити вихід yesдо входу ./script. Тож, коли ./scriptзапитується про введення користувача, він замість цього отримає вихід yes. Вихід yes- це нескінченний потік, за yяким слідує новий рядок. Насправді так, ніби користувач звертається yза кожним запитанням ./script.

Якщо ви хочете сказати ні ( n) замість так ( y), можете зробити це так:

$ yes n | ./script

Зауважте, що деякі інструменти мають можливість завжди вважати yesяк відповідь. Ось, наприклад, дивіться тут: Обход запиту так / ні в "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'і stdin отримає вхід з імені файлу echo. І bash скаржиться, оскільки файл не існує.


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

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

нічого не працює з 'бродячим знищенням' на центосах
Дрю

Злий легко! Працює на імпорті даних 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 script.sh
expect "Are you sure you want to continue connecting (yes/no)?"
send "yes"

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

Очікуйте в межах Bash


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.