Apa yang setara dengan Linux untuk jeda DOS?

236

Saya memiliki skrip Bash shell di mana saya ingin menjeda eksekusi sampai pengguna menekan tombol. Dalam DOS, ini mudah dilakukan dengan perintah "pause". Apakah ada padanan Linux yang dapat saya gunakan dalam skrip saya?

jt.
sumber

Jawaban:

329

read Melakukan hal ini:

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

The -n1menetapkan bahwa hanya menunggu satu karakter. The -rmenempatkan ke dalam modus mentah, yang diperlukan karena jika tidak, jika Anda menekan sesuatu seperti garis miring terbalik, itu tidak mendaftar sampai Anda menekan tombol berikutnya. The -pmenspesifikasikan prompt, yang harus dikutip jika mengandung spasi. The keyArgumen ini hanya diperlukan jika Anda ingin tahu mana kunci mereka ditekan, dalam hal ini Anda dapat mengaksesnya melalui $key.

Jika Anda menggunakan Bash, Anda juga dapat menentukan batas waktu dengan -t, yang menyebabkan pembacaan mengembalikan kegagalan ketika tombol tidak ditekan. Jadi misalnya:

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
Jim
sumber
5
Sebenarnya, itu akan terjadi "Enter any non-NUL character to continue". Beberapa kunci tidak mengirim karakter apa pun (seperti Ctrl...) dan beberapa mengirim lebih dari satu (seperti F1, Home...). bashmengabaikan karakter NUL.
Stephane Chazelas
2
Biasanya adalah ide yang lebih baik untuk meminta kunci tertentu seperti enter, space atau Y. "ANY" dapat membingungkan bagi beberapa pengguna, ada TAB-key jadi mengapa tidak ada ANY-key dan pasti ada kunci yang berpotensi berbahaya seperti ESCAPE, CTRL, CMD, tombol power, dll. Ini tidak begitu relevan lagi hari ini, karena saat ini konsol biasanya hanya digunakan oleh pengguna komputer canggih yang akan mengartikan "tombol apa saja" dengan benar. Manual Desain Apple 2, cukup tua, memiliki bagian yang menarik yang ditujukan untuk subjek ini ( apple2scans.net/files/1982-A2F2116-m-a2e-aiiedg.pdf ).
Gellweiler
3
Jika Anda menggunakan pesan, Press a key to continue...maka pengguna awam pun dapat menemukan akunci dan menekannya; o)
DJDaveMark
1
Ini akan memiliki masalah dengan command | myscript.shatau myscript.sh | command. Lihat jawaban ini untuk solusinya.
Tom Hale
Jika ada yang read: 1: read: Illegal option -nmemastikan untuk membungkus perintah Anda di bash -c 'command && command'dll karena kesalahan itu kemungkinan berasal sh. Saya melakukan ini dalam perintah pembungkus Lando.
Elijah Lynn
155

Saya menggunakan cara-cara ini banyak yang sangat pendek, dan mereka seperti solusi @theunamedguy dan @ Jim, tetapi dengan mode timeout dan silent sebagai tambahan.

Saya terutama menyukai kasus terakhir dan menggunakannya dalam banyak skrip yang berjalan dalam satu lingkaran sampai pengguna menekan Enter.

Perintah

  • Masukkan solusi

    read -rsp $'Press enter to continue...\n'
  • Solusi melarikan diri (dengan -d $ '\ e')

    read -rsp $'Press escape to continue...\n' -d $'\e'
  • Solusi utama apa saja (dengan -n 1)

    read -rsp $'Press any key to continue...\n' -n 1 key
    # echo $key
  • Pertanyaan dengan pilihan yang dipilih sebelumnya (dengan -ei $ 'Y')

    read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;
    # echo $key
  • Solusi batas waktu (dengan -t 5)

    read -rsp $'Press any key or wait 5 seconds to continue...\n' -n 1 -t 5;
  • Tidur alias ditingkatkan

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

Penjelasan

-r menentukan mode mentah, yang tidak memungkinkan karakter gabungan seperti "\" atau "^".

-s menentukan mode diam, dan karena kita tidak perlu output keyboard.

-p $ ' prompt ' menentukan prompt, yang harus antara $ 'dan' untuk membiarkan spasi dan lolos dari karakter. Hati-hati, Anda harus menempatkan antara tanda kutip tunggal dengan simbol dolar untuk mendapatkan manfaat dari karakter yang lolos, jika tidak, Anda dapat menggunakan kutipan sederhana.

-d $ ' \ e ' menetapkan escappe sebagai pembatas pembatas, jadi sebagai karakter terakhir untuk entri saat ini, ini dimungkinkan untuk menempatkan karakter apa pun tetapi hati-hati untuk menempatkan karakter yang dapat diketik pengguna.

-n 1 menetapkan bahwa itu hanya membutuhkan satu karakter.

-e menentukan mode readline.

-i $ ' Y ' menentukan Y sebagai teks awal dalam mode readline.

-t 5 menentukan batas waktu 5 detik

tombol serve jika Anda perlu mengetahui input, dalam kasus -n1, tombol yang telah ditekan.

$? berfungsi untuk mengetahui kode keluar dari program terakhir, untuk dibaca, 142 jika batas waktu, 0 input yang benar. Masukkan $? dalam variabel sesegera mungkin jika Anda perlu mengujinya setelah perintah somes, karena semua perintah akan menulis ulang $?

y.petremann
sumber
1
+1 untuk menjelaskan -s; man readdan read --helpbantuan tidak membantu di Ubuntu 10.04.1 LTS. Edit: help readlakukan; Apakah sisanya sudah ditinggalkan?
Cees Timmerman
1
1+ untuk penjelasan hebat: tetapi saya dapat read: -i: invalid optionuntuk mantan. read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;di #osx read -rp $'kill-server: Are you sure (Y/n) : ' -d $'Y' key;bekerja untuk saya sebagai gantinya. `
Tino Rüb
Saya tidak tahu cara kerjanya di OSX tapi saya sudah melakukan beberapa tes dan -ibekerja dengan baik di Ubuntu, juga saya tidak tahu bagaimana jika -dbekerja dengan cara yang sama di OSX.
y.petremann
seseorang dapat bekerja dengan cepat dan baik dengan menggunakan echo sebelum membaca, akhirnya echo -n
THESorcerer
15

readtanpa parameter apa pun hanya akan berlanjut jika Anda menekan enter. pausePerintah DOS akan dilanjutkan jika Anda menekan tombol apa saja. Gunakan read –n1jika Anda menginginkan perilaku ini.

xsl
sumber
15

Ini bekerja untuk saya di berbagai rasa Linux, di mana beberapa solusi lain tidak (termasuk yang paling populer di sini). Saya pikir itu lebih mudah dibaca juga ...

echo Press enter to continue; read dummy;

Perhatikan bahwa variabel perlu diberikan sebagai argumen read.

Terima kasih
sumber
jawaban ini menyelesaikan masalah saya, jika saya salin dan tempel baris ini dan untuk beberapa alasan saya mendapat lebih banyak baris yang ditambahkan, baris yang ditambahkan tidak dieksekusi, seperti dengan jeda DOS
Sérgio
10

read -n1tidak portabel. Cara portabel untuk melakukan hal yang sama mungkin:

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

Selain menggunakan read, hanya untuk menekan ENTERuntuk melanjutkan, Anda dapat melakukan:

sed -n q </dev/tty
mikeserv
sumber
2
status=nonejuga tidak portabel. Alihkan stdout dan stderr ke / dev / null saja. read -r line < /dev/ttyakan enought untuk menekan ENTER ... .
Stephane Chazelas
@StephaneChezales terima kasih - saya tidak tahu itu. sakit memperbaikinya sekarang. Terima kasih lagi - diperbaiki. Ngomong-ngomong, Anda adalah sumber informasi berharga yang tak berdasar.
mikeserv
1
Perhatikan juga settings=$(stty -g); stty raw; dd ...; stty "$settings"untuk menyimpan dan mengembalikan pengaturan tty.
Stephane Chazelas
@StephaneChezales - saya tidak ada di depan komputer - apakah menurut Anda trpengeditan dapat bekerja juga?
mikeserv
1
Tidak, karena trakan menyangga outputnya sebagai pipa, dan keyboard non-AS memiliki kunci yang mengirim karakter di luar \1-\177jangkauan. ddadalah cara idiomatis di sini.
Stephane Chazelas
2

Jika Anda hanya perlu menjeda loop atau skrip, dan Anda senang menekan Enter daripada tombol apa pun, maka readdengan sendirinya akan melakukan pekerjaan.

do_stuff
read
do_more_stuff

Ini tidak ramah pengguna akhir, tetapi mungkin cukup dalam kasus di mana Anda menulis skrip cepat untuk diri sendiri, dan Anda perlu menjeda untuk melakukan sesuatu secara manual di latar belakang.

mwfearnley
sumber
Ini benar, tetapi untuk basis data, sangat membantu untuk menunjukkan contoh.
SDsolar
Terima kasih, saya menerima saran Anda. Hanya menulis nama perintah tidak terlalu jelas di belakang.
mwfearnley
1

Coba ini:

function pause(){
   read -p "$*"
}
Alex Fort
sumber
1
Adakah yang bisa menjelaskan mengapa hal ini dibatalkan? Apakah karena kurangnya konten atau ini solusi yang buruk?
3ocene
4
@ 3ocene Ini tidak menunjukkan penggunaan fungsi yang dibuat; ditambah lagi kekurangan penjelasan ini.
parvus
Sepakat. Bisakah Anda menunjukkan contoh bagaimana fungsi ini dipanggil?
SDsolar
1

Fungsi ini berfungsi di kedua 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
0

Ya untuk menggunakan read- dan ada beberapa penyesuaian yang membuatnya paling berguna baik crondi terminal maupun di terminal.

Contoh:

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

-N 120 membuat waktu pernyataan baca habis setelah 2 menit sehingga tidak menghalangi cron .

Di terminal itu memberikan 2 menit untuk melihat berapa lama rsync perintah untuk dieksekusi.

Lalu selanjutnya echo adalah agar bash prompt berikutnya akan muncul di baris berikutnya.

Kalau tidak, itu akan ditampilkan pada baris yang sama langsung setelah "melanjutkan ..." ketika Enterditekan di terminal.

SDsolar
sumber