Что Linux эквивалентно паузе DOS?

236

У меня есть сценарий оболочки Bash, в котором я хотел бы приостановить выполнение, пока пользователь не нажмет клавишу. В DOS это легко сделать с помощью команды «пауза». Есть ли эквивалент Linux, который я могу использовать в своем сценарии?

JT.
источник

Ответы:

329

read Является ли это:

user@host:~$ read -n1 -r -p "Press any key to continue..." key
[...]
user@host:~$ 

В -n1указывает , что он ждет только одного символа. Команда -rпереводит его в необработанный режим, что необходимо, поскольку в противном случае, если вы нажмете что-то вроде обратной косой черты, оно не будет зарегистрировано, пока вы не нажмете следующую клавишу. В -pуказывает подсказка, которая должна быть указана , если он содержит пробелы. keyАргумент нужен только если вы хотите знать , какой ключ они вдавленные, в этом случае вы можете получить доступ через $key.

Если вы используете Bash, вы также можете указать тайм-аут с помощью -tкоторого чтение будет возвращать ошибку, когда клавиша не нажата. Так, например:

read -t5 -n1 -r -p 'Press any key in the next five seconds...' key
if [ "$?" -eq "0" ]; then
    echo 'A key was pressed.'
else
    echo 'No key was pressed.'
fi
Джим
источник
5
Строго говоря, так и будет "Enter any non-NUL character to continue". Некоторые ключи не отправляют никаких символов (например, Ctrl...), а некоторые - более одного (например F1, Home...). bashигнорирует NUL-символы
Стефан Шазелас
2
Обычно лучше спросить конкретный ключ, такой как ввод, пробел или Y. «ЛЮБОЙ» может вводить в заблуждение некоторых пользователей, есть клавиша TAB, так почему нет ЛЮБОГО ключа и наверняка есть ключи, которые потенциально опасны как ESCAPE, CTRL, CMD, кнопка питания и т. д. Это уже не так актуально сегодня, потому что в настоящее время консоль обычно используется только опытными пользователями компьютеров, которые будут правильно интерпретировать «ЛЮБОЙ ключ». Руководство по дизайну Apple 2, довольно старое, имеет интересный раздел, посвященный этой теме ( apple2scans.net/files/1982-A2F2116-m-a2e-aiiedg.pdf ).
Геллвайлер
3
Если вы вместо этого используете сообщение, Press a key to continue...то даже начинающие пользователи смогут найти aключ и нажать его; o)
DJDaveMark
1
Это будет иметь проблемы с command | myscript.shили myscript.sh | command. Смотрите этот ответ для решения.
Том Хейл
Если кто-то получит, read: 1: read: Illegal option -nобязательно включите вашу команду bash -c 'command && command'и т. Д., Поскольку эта ошибка, вероятно, из sh. Я делаю это в команде оболочки Ландо.
Элайджа Линн
155

Я часто использую эти способы, которые очень короткие, и они похожи на решения @theunamedguy и @Jim, но с дополнительным таймаутом и бесшумным режимом.

Мне особенно нравится последний случай, и я использую его во многих сценариях, которые запускаются в цикле, пока пользователь не нажмет Enter.

команды

  • Введите решение

    read -rsp $'Press enter to continue...\n'
  • Escape-решение (с -d $ '\ e')

    read -rsp $'Press escape to continue...\n' -d $'\e'
  • Любое ключевое решение (с -n 1)

    read -rsp $'Press any key to continue...\n' -n 1 key
    # echo $key
  • Вопрос с предварительно выбранным выбором (с -ei $ 'Y')

    read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;
    # echo $key
  • Решение по тайм-ауту (с -t 5)

    read -rsp $'Press any key or wait 5 seconds to continue...\n' -n 1 -t 5;
  • Сон улучшенный псевдоним

    read -rst 0.5; timeout=$?
    # echo $timeout

объяснение

-r указывает необработанный режим, который не допускает комбинированные символы, такие как «\» или «^».

-s определяет режим без вывода сообщений, и потому что нам не нужен вывод с клавиатуры.

-p $ ' prompt ' указывает подсказку, которая должна быть между $ и ', чтобы пропустить пробелы и экранированные символы. Будьте осторожны, вы должны ставить между одинарными кавычками с символом доллара, чтобы использовать экранированные символы, в противном случае вы можете использовать простые кавычки.

-d $ ' \ e ' определяет escappe в качестве символа-разделителя, так что в качестве последнего символа для текущей записи можно использовать любой символ, но будьте осторожны с символом, который может ввести пользователь.

-n 1 указывает, что ему нужен только один символ.

-e указывает режим чтения.

-i $ ' Y ' указывает Y как исходный текст в режиме чтения строки.

-t 5 указывает время ожидания 5 секунд

Клавиша служит в случае, если вам нужно знать ввод, в -n1 случае - нажатую клавишу.

$? служит для того, чтобы узнать код завершения последней программы, для чтения, 142 в случае тайм-аута, 0 правильный ввод. Положить $? в переменную как можно скорее, если вам нужно проверить ее после некоторых команд, потому что все команды переписывают $?

y.petremann
источник
1
+1 за объяснение -s; man readи read --helpпомощь не помогла на Ubuntu 10.04.1 LTS. Редактировать: help readсделал; остальное не рекомендуется?
Сис Тиммерман
1
1+ за отличное объяснение: но я получил read: -i: invalid optionза бывшего. read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;на #osx read -rp $'kill-server: Are you sure (Y/n) : ' -d $'Y' key;у меня работает вместо этого. `
Тино Руб
Я не знаю, как это работает на OSX, но я провел несколько тестов и -iотлично работает на Ubuntu, также я не знаю, как, если -dработает так же на OSX.
y.petremann
можно быстро и приятно обойти приглашение, используя echo перед прочтением, в конце концов echo -n
THESorcerer
15

readбез каких-либо параметров будет продолжаться только при нажатии Enter. Команда DOS pauseпродолжится, если вы нажмете любую клавишу. Используйте, read –n1если вы хотите это поведение.

XSL
источник
15

Это сработало для меня во многих разновидностях Linux, где некоторые из этих других решений не (в том числе самые популярные здесь). Я думаю, что это также более читабельно ...

echo Press enter to continue; read dummy;

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

BuvinJ
источник
этот ответ решит мою проблему, если я скопирую и вставлю эту строку и по какой-то причине я добавлю больше строк, добавленные строки не будут выполнены, как это было с паузой в DOS
Sérgio
10

read -n1не является портативным Портативный способ сделать то же самое может быть:

(   trap "stty $(stty -g;stty -icanon)" EXIT
    LC_ALL=C dd bs=1 count=1 >/dev/null 2>&1
)   </dev/tty

Помимо использования read, просто нажмите ENTERдля продолжения запроса, вы можете сделать:

sed -n q </dev/tty
mikeserv
источник
2
status=noneтоже не портативно. Вместо этого перенаправьте stdout и stderr в / dev / null. read -r line < /dev/ttyбудет прийти для печати ENTER ... .
Стефан Шазелас
@StephaneChezales спасибо - я этого не знал. сейчас исправлю. Еще раз спасибо - исправлено. Кстати, ты бездонный источник полезной информации.
mikeserv
1
Также обратите внимание на settings=$(stty -g); stty raw; dd ...; stty "$settings"сохранение и восстановление настроек tty.
Стефан Шазелас
@StephaneChezales - я не за компьютером - ты думаешь, что trредактирование тоже может сработать?
mikeserv
1
Нет, потому trчто буферизировал бы свой вывод как конвейер, а у неамериканских клавиатур есть клавиши, которые отправляют символы за пределы \1-\177диапазона. ddэто идиоматический способ здесь.
Стефан Шазелас
2

Если вам просто нужно приостановить цикл или сценарий, и вы готовы нажать клавишу Enter вместо любой клавиши, тогда readона сама сделает эту работу.

do_stuff
read
do_more_stuff

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

mwfearnley
источник
Это правда, но для базы данных наиболее полезно показать пример.
SDsolar
Спасибо, я принял ваш совет на борт. Просто задание имени команды не очень понятно задним числом.
mwfearnley
1

Попробуй это:

function pause(){
   read -p "$*"
}
Алекс Форт
источник
1
Может кто-нибудь объяснить, почему это понизили? Это из-за отсутствия контента или это плохое решение?
3
4
@ 3ocene Это не показывает использование созданной функции; плюс этому не хватает объяснения.
parvus
Согласовано. Можете ли вы показать пример того, как эта функция вызывается?
SDsolar
1

Эта функция работает как bashи zsh, так и обеспечивает ввод / вывод на терминал:

# Prompt for a keypress to continue. Customise prompt with $*
function pause {
  >/dev/tty printf '%s' "${*:-Press any key to continue... }"
  [[ $ZSH_VERSION ]] && read -krs  # Use -u0 to read from STDIN
  [[ $BASH_VERSION ]] && </dev/tty read -rsn1
  printf '\n'
}
export_function pause

Поместите это .{ba,z}shrcдля Великой Справедливости!

Том Хейл
источник
0

Да, для использования read- и есть пара твиков, которые делают его наиболее полезным как cronв терминале, так и в терминале.

Пример:

time rsync (options)
read -n 120 -p "Press 'Enter' to continue..." ; echo " "

Параметр -n 120 истекает через 2 минуты для оператора чтения, поэтому он не блокируется cron.

В терминале это дает 2 минуты, чтобы увидеть, сколько времени rsyncпотребовалось для выполнения команды.

Затем последующее echoприглашение bash появится на следующей строке.

В противном случае он будет отображаться в той же строке сразу после «продолжить ...» при Enterнажатии на терминале.

SDsolar
источник