Tekan spasi untuk melanjutkan

74

Bagaimana cara menghentikan skrip bash hingga pengguna menekan Space?

Saya ingin memiliki pertanyaan dalam skrip saya

Tekan spasi untuk melanjutkan atau CTRL+ Cuntuk keluar

dan kemudian skrip harus berhenti dan menunggu sampai Space ditekan.

rubo77
sumber
Semua ini dan lebih banyak dibahas dalam SO T&J BTW ini: Apa yang setara dengan linux untuk jeda DOS?
slm
terkait: unix.stackexchange.com/questions/293940/…
Trevor Boyd Smith

Jawaban:

58

Anda bisa menggunakan read:

read -n1 -r -p "Press space to continue..." key

if [ "$key" = '' ]; then
    # Space pressed, do something
    # echo [$key] is empty when SPACE is pressed # uncomment to trace
else
    # Anything else pressed, do whatever else.
    # echo [$key] not empty
fi
AleksanderKseniya
sumber
12
Anda harus menambahkan -s untuk tidak mencetak karakter yang ditekan keluar pada terminal. Dan tambahkan linebreak di bagian akhir, atau output akan terus langsung di baris yang sama seperti pertanyaan. Yang terbaik adalah:read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
rubo77
1
Skrip ini tidak berfungsi. Baru saja mengujinya di linux Red Hat ... elseBlok selalu berjalan, bahkan ketika bilah spasi ditekan.
robert
3
@robert Itu karena Anda tidak menggunakan bash. Ini berfungsi jika Anda menggunakannya read _sebagai gantinya, jika Anda memiliki beberapa shell selain bash.
Niklas Rosencrantz
Haruskah ''mengandung ruang di dalam?
Jose Antonio Dura Olmos
Ini ''untuk string kosong. Tidak ada ruang di dalam. Saya kira, itu juga cocok, jika Anda memasukkan ENTER atau TAB
rubo77
45

Metode yang dibahas dalam T&J SO ini kemungkinan merupakan kandidat terbaik untuk alternatif pauseperilaku yang biasa Anda lakukan di Windows saat melakukan file BAT.

$ read -rsp $'Press any key to continue...\n' -n1 key

Contoh

Di sini saya menjalankan di atas dan kemudian cukup menekan tombol apa saja, dalam hal ini Dkuncinya.

$ read -rsp $'Press any key to continue...\n' -n1 key
Press any key to continue...
$ 

Referensi

slm
sumber
Maksud saya mengapa $sebelum string di sini -rsp $'Press:?
rubo77
2
@ rubo77 - ah. Begitulah cara Anda dapat melakukan string literal dengan karakter khusus. Bentuknya: $ '...'
slm
1
@ rubo77 - itu berbeda. Itu tanda dolar dengan tanda kutip ganda, saya menggunakan tanda kutip dolar dengan tanda kutip tunggal. Silakan hapus komentar itu, itu salah.
slm
1
Oh saya mengerti. Jika Anda menempatkan urutan lolos di dalam prompt-string. lihat wiki.bash-hackers.org/syntax/quoting#ansi_c_like_strings
rubo77
@ rubo77 - ya notasi itu memungkinkan untuk urutan melarikan diri untuk dimasukkan tanpa echo -e "..."garis tambahan . Jauh lebih ringkas dalam situasi itu.
slm
6
hold=' '
printf "Press 'SPACE' to continue or 'CTRL+C' to exit : "
tty_state=$(stty -g)
stty -icanon
until [ -z "${hold#$in}" ] ; do
    in=$(dd bs=1 count=1 </dev/tty 2>/dev/null)
done
stty "$tty_state"

Ini sekarang mencetak prompt tanpa baris baru, menangani dengan CTRL+Candal, sttyhanya memanggil sesering yang diperlukan, dan mengembalikan tty mengendalikan ke keadaan di mana sttymenemukannya. Cari man sttyinformasi tentang cara mengontrol gema, mengontrol karakter, dan semuanya secara eksplisit.

Anda mungkin juga melakukan ini:

printf "Press any key to continue or 'CTRL+C' to exit : "
(tty_state=$(stty -g)
stty -icanon
LC_ALL=C dd bs=1 count=1 >/dev/null 2>&1
stty "$tty_state"
) </dev/tty

Anda dapat melakukannya dengan ENTER, tanpa [tes ]dan tanpa sttysuka:

sed -n q </dev/tty
mikeserv
sumber
5

Anda dapat membuat fungsi untuk itu:

pause(){
 read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
}

Maka Anda dapat menggunakan ini di mana saja dalam skrip Anda:

pause
rubo77
sumber
jika Anda baru menggunakan shell scripting - Anda harus meletakkan fungsi di bagian atas skrip Anda sebelum menggunakannya
Richard
3

malas satu liner:

echo "Press any key to continue or Ctrl+C to cancel"
read && do_something.sh

Kerugiannya adalah Anda kehilangan kendali ketika pengguna menekan ctrl + c. Script akan selalu keluar dengan kode 130 dalam kasus itu.

gcb
sumber
2

Pengaturan IFSuntuk mengosongkan string akan menekan perilaku default baca dari pemotongan ruang putih.

try_this() {
  echo -n "Press SPACE to continue or Ctrl+C to exit ... "
  while true; do
    # Set IFS to empty string so that read doesn't trim
    # See http://mywiki.wooledge.org/BashFAQ/001#Trimming
    IFS= read -n1 -r key
    [[ $key == ' ' ]] && break
  done
  echo
  echo "Continuing ..."
}
try_this

UPDATE 2018-05-23: Kita dapat menyederhanakan ini dengan menggunakan variabel REPLY, yang tidak tunduk pada pemisahan kata:

try_this() {
  echo -n "Press SPACE to continue or Ctrl+C to exit ... "
  while true; do
    read -n1 -r
    [[ $REPLY == ' ' ]] && break
  done
  echo
  echo "Continuing ..."
}
try_this
Robin A. Meade
sumber
1

Inilah cara yang bekerja di keduanya bashdan zsh, dan memastikan I / O ke terminal:

# 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

Taruh di dalam Anda .{ba,z}shrcuntuk Keadilan Hebat!

Tom Hale
sumber