Що таке еквівалент Linux паузі DOS?


236

У мене є сценарій оболонки Bash, в якому я хотів би призупинити виконання, поки користувач не натисне клавішу. У DOS це легко зробити за допомогою команди "пауза". Чи є еквівалент Linux, який я можу використовувати у своєму сценарії?

Відповіді:


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
Зазвичай, краще взяти запит на певний ключ, наприклад, enter, space або Y. "БУДЬ-ЯКОГО" може заплутати деяких користувачів. Існує клавіша TAB, тож чому немає жодного ключа та, звичайно, є ключі, які є потенційно небезпечними наприклад ESCAPE, CTRL, CMD, кнопка живлення тощо. Це сьогодні вже не так актуально, тому що в даний час консоллю зазвичай користуються лише досвідчені користувачі комп'ютерів, які правильно інтерпретують "будь-яку клавішу". Посібник з дизайну Apple 2, важкий досить старий, має цікавий розділ, присвячений цій темі ( apple2scans.net/files/1982-A2F2116-m-a2e-aiiedg.pdf ).
Gellweiler

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. Я роблю це в команді обгортки Lando.
Ілля Лінн

155

Я дуже часто використовую ці способи, які є дуже короткими, і вони схожі на рішення @theunamedguy та @Jim, але крім того, з тимчасовим і безшумним режимом.

Я особливо люблю останній випадок і використовую його у багатьох сценаріях, які працюють у циклі, поки користувач не натисне Enter.

Команди

  • Введіть рішення

    read -rsp $'Press enter to continue...\n'
  • Розв’язання (з -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 правильного введення. Покласти $? у змінній якнайшвидше, якщо вам потрібно перевірити її після команд somes, тому що всі команди переписали б $?


1
+1 для пояснення -s; man readі read --helpдопомога не допомогла на Ubuntu 10.04.1 LTS. Редагувати: help readзробив; чи решта застаріла?
Cees Timmerman

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;працює замість мене. `
Tino Rüb

Я не знаю, як це працює на OSX, але я зробив тест і -iчудово працює на Ubuntu, також не знаю, як -dпрацює так само на OSX.
y.petremann

можна обійти підказку дуже швидко і приємно, використовуючи ехо перед читанням, зрештою відлуння -n
THESorcerer

15

readбез будь-яких параметрів продовжуватиметься лише якщо натиснути клавішу Enter. Команда DOS pauseпродовжується, якщо натиснути будь-яку клавішу. Використовуйте, read –n1якщо ви хочете такої поведінки.


15

Це працювало для мене на різних варіантах Linux, де деяких з цих інших рішень не було (включаючи найпопулярніші тут). Я думаю, що це також читабельніше ...

echo Press enter to continue; read dummy;

Зауважте, що змінну потрібно подавати як аргумент read.


ця відповідь вирішить мою проблему, якщо я скопіюю та вставив цей рядок, і я чомусь додав більше рядків, додані рядки не виконуються, як це було з паузою 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

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

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


Це правда, але для бази даних найкраще показати приклад.
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натискається в терміналі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.