naciśnij spację aby kontynuować


73

Jak zatrzymać skrypt bash, dopóki użytkownik nie naciśnie Space?

Chciałbym mieć pytanie w swoim skrypcie

Naciśnij spację, aby kontynuować lub CTRL+, Caby wyjść

a następnie skrypt powinien się zatrzymać i poczekać, aż zostanie naciśnięty klawisz Space.


Wszystko to i więcej zostało omówione w tym SO Q&A BTW: Jaki jest linux równoważny pauzie DOS?
slm


Odpowiedzi:


58

Możesz użyć 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

12
Powinieneś dodać -s, aby nie drukować wciśniętego znaku na terminalu. I dodaj podział linii na końcu, w przeciwnym razie dane wyjściowe będą kontynuowane bezpośrednio w tym samym wierszu, co pytanie. Najlepiej byłoby:read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
rubo77

1
Ten skrypt nie działa. Właśnie przetestowałem go na linuksie Red Hata ... elseBlok zawsze działa, nawet po naciśnięciu spacji.
Robert

3
@robert To dlatego, że nie używasz bash. Działa, jeśli używasz read _zamiast tego, jeśli masz inną powłokę niż bash.
Niklas Rosencrantz

Czy w ''środku powinna znajdować się spacja?
Jose Antonio Dura Olmos

To jest ''na pusty ciąg. Brak miejsca w środku. Sądzę, że pasuje również, jeśli wpiszesz ENTER lub TAB
rubo77

44

Metoda omówiona w tym SO Q&A jest prawdopodobnie najlepszym kandydatem na alternatywę dla pausezachowania, do którego przyzwyczajasz się w systemie Windows podczas wykonywania plików BAT.

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

Przykład

Tutaj uruchamiam powyższe, a następnie po prostu naciskam dowolny klawisz, w tym przypadku Dklawisz.

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

Bibliografia


Mam na myśli dlaczego $przed ciąg tutaj tutaj -rsp $'Press:?
rubo77

2
@ rubo77 - ah. W ten sposób możesz napisać dosłownie ciąg znaków specjalnych. Ma postać: $ '...'
slm

1
@ rubo77 - to jest inne. To znak dolara z podwójnymi cudzysłowami, użyłem dolara z pojedynczymi cudzysłowami. Usuń ten komentarz, jest nieprawidłowy.
slm

1
Oh rozumiem. Jeśli wstawisz sekwencje specjalne w ciągu zachęty. patrz wiki.bash-hackers.org/syntax/quoting#ansi_c_like_strings
rubo77

@ rubo77 - tak, że notacja pozwala na dołączenie sekwencji specjalnych bez dodatkowych echo -e "..."linii. W takich sytuacjach jest znacznie bardziej kompaktowy.
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"

To teraz drukuje wiersz bez spływu nowej linii, uchwyty CTRL+Cniezawodnie wywołuje sttytylko tak często, jak to konieczne, i przywraca tty kontrolnego dokładnie do stanu, w którym sttyznalazł. Poszukaj man sttyinformacji o tym, jak jawnie kontrolować echa, kontrolować znaki i wszystko.

Możesz także to zrobić:

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

Możesz to zrobić ENTERbez [testów ]i bez stty:

sed -n q </dev/tty

5

Możesz stworzyć dla niego funkcję:

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

Następnie możesz użyć tego wszędzie w skrypcie:

pause

jeśli dopiero zaczynasz korzystać ze skryptów powłoki - przed użyciem musisz umieścić tę funkcję u góry skryptu
Richard

3

leniwy jeden wkładka:

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

wadą jest utrata kontroli, gdy użytkownik naciśnie ctrl + c. W takim przypadku skrypt zawsze kończy działanie z kodem 130.


2

Ustawienia IFSpustego ciągu pomijają domyślne zachowanie przycinania białych znaków podczas odczytu.

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

AKTUALIZACJA 23.05.2018: Możemy to uprościć, używając zmiennej REPLY, która nie podlega podziałowi słów:

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

1

Oto sposób, który działa w obie bashi zshoraz zapewnia I / O terminala:

# 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

Włóż to do swojej .{ba,z}shrcWielkiej Sprawiedliwości!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.