bấm Space để đi tiếp


73

Làm cách nào để dừng tập lệnh bash cho đến khi người dùng nhấn Space?

Tôi muốn có câu hỏi trong kịch bản của tôi

Nhấn phím cách để tiếp tục hoặc CTRL+ Cđể thoát

và sau đó tập lệnh sẽ dừng lại và đợi cho đến khi Space được nhấn.


Tất cả những điều này và nhiều hơn nữa được đề cập trong SO Q & A BTW này: linux tương đương với tạm dừng DOS là gì?
slm


Câu trả lời:


58

Bạn có thể sử dụng 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
Bạn nên thêm -s để không in ký tự được nhấn ra trên thiết bị đầu cuối. Và thêm một ngắt dòng ở cuối, hoặc đầu ra sẽ tiếp tục trực tiếp trong cùng một dòng như câu hỏi. Tốt nhất sẽ là:read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
rubo77

1
Kịch bản này không hoạt động. Chỉ cần thử nghiệm nó trên Red Hat linux ... elseKhối luôn chạy, ngay cả khi nhấn phím cách.
robert

3
@robert Đó là vì bạn không sử dụng bash. Nó hoạt động nếu bạn sử dụng read _thay thế, nếu bạn có một số vỏ khác bash.
Niklas Rosencrantz

Có nên ''chứa một không gian bên trong?
Jose Antonio Dura Olmos

Đây là ''một chuỗi trống. Không có không gian bên trong. Tôi đoán, nó cũng phù hợp, nếu bạn nhập ENTER hoặc TAB
rubo77

44

Phương pháp được thảo luận trong Câu hỏi và trả lời SO này có thể là ứng cử viên tốt nhất để thay thế cho pausehành vi mà bạn quen thuộc trên Windows khi thực hiện các tệp BAT.

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

Thí dụ

Ở đây tôi đang chạy ở trên và sau đó chỉ cần nhấn bất kỳ phím nào, trong trường hợp này là Dphím.

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

Người giới thiệu


Ý tôi là tại sao $trước chuỗi ở đây : -rsp $'Press?
rubo77

2
@ rubo77 - à. Đó là cách bạn có thể thực hiện một chuỗi ký tự với các ký tự đặc biệt. Đó là hình thức: $ '...'
slm

1
@ rubo77 - đó là khác nhau. Đó là một ký hiệu đô la với dấu ngoặc kép, tôi đã sử dụng một đô la với dấu ngoặc đơn. Hãy xóa bình luận đó, nó sai.
slm

1
À, tôi hiểu rồi. Trong trường hợp bạn đặt các chuỗi đã thoát bên trong chuỗi dấu nhắc. xem wiki.bash-hackers.org/syntax/quote#ansi_c_like_strings
rubo77

@ rubo77 - vâng, ký hiệu đó cho phép các chuỗi thoát được bao gồm trong bất kỳ echo -e "..."dòng bổ sung nào . Nó nhỏ gọn hơn nhiều trong những tình huống đó.
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"

Điều này bây giờ in một dấu nhắc mà không có dòng mới, xử lý CTRL+Cđáng tin cậy, sttychỉ gọi thường xuyên khi cần thiết và khôi phục tty kiểm soát để chính xác trạng thái sttytìm thấy nó. Xem xét man sttythông tin về cách kiểm soát tiếng vang, điều khiển nhân vật và tất cả.

Bạn cũng có thể làm điều này:

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

Bạn có thể làm điều đó với ENTER, không có [bài kiểm tra ]và không sttythích:

sed -n q </dev/tty

5

Bạn có thể tạo một chức năng cho nó:

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

Sau đó, bạn có thể sử dụng điều này ở mọi nơi trong tập lệnh của bạn:

pause

nếu bạn chưa quen với kịch bản shell - bạn cần đặt chức năng ở đầu tập lệnh trước khi sử dụng nó
Richard

3

lười một lớp lót:

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

nhược điểm là bạn mất kiểm soát khi người dùng nhấn ctrl + c. Kịch bản sẽ luôn thoát với mã 130 trong trường hợp đó.


2

Cài đặt IFScho chuỗi trống ngăn chặn hành vi mặc định của việc đọc khoảng trắng.

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

CẬP NHẬT 2018-05-23: Chúng tôi có thể đơn giản hóa điều này bằng cách sử dụng biến REPLY, không thuộc đối tượng chia từ:

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

Đây là một cách hoạt động trong cả hai bashzsh, và đảm bảo I / O cho thiết bị đầu cuối:

# 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

Đặt nó trong .{ba,z}shrcCông lý vĩ đại của bạn !

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.