เทียบเท่ากับ Linux คืออะไร DOS หยุดชั่วคราว?


236

ฉันมีสคริปต์ Bash shell ที่ฉันต้องการหยุดการทำงานชั่วคราวจนกว่าผู้ใช้จะกดปุ่ม ใน DOS สิ่งนี้สามารถทำได้อย่างง่ายดายด้วยคำสั่ง "หยุดชั่วคราว" มีลินุกซ์เทียบเท่าที่ฉันสามารถใช้ในสคริปต์ของฉันได้หรือไม่

คำตอบ:


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
Stephane Chazelas

2
โดยปกติแล้วจะเป็นการดีกว่าถ้าคุณขอคีย์เฉพาะเช่น enter, space หรือ Y "ANY" อาจสร้างความสับสนให้กับผู้ใช้บางคนมี TAB-key ดังนั้นทำไมไม่มีคีย์ใด ๆ และแน่นอนว่ามีคีย์ที่อาจเป็นอันตราย เช่น 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ดูคำตอบนี้สำหรับวิธีแก้ปัญหา
Tom Hale

ถ้าใครได้รับการread: 1: read: Illegal option -nตรวจสอบให้แน่ใจที่จะตัดคำสั่งของคุณในbash -c 'command && command'ฯลฯ shเป็นข้อผิดพลาดที่น่าจะมาจาก ฉันกำลังทำสิ่งนี้ในคำสั่ง Lando wrapper
Elijah Lynn

155

ฉันใช้วิธีการเหล่านี้จำนวนมากที่สั้นมากและพวกเขาก็เหมือน @theunamedguy และ @Jim โซลูชั่น แต่ด้วยการหมดเวลาและโหมดเงียบนอกจากนี้

Enterโดยเฉพาะอย่างยิ่งผมรักกรณีที่ผ่านมาและใช้มันในจำนวนมากของสคริปที่วิ่งในวงจนกว่าผู้ใช้กด

คำสั่ง

  • ป้อนวิธีแก้ปัญหา

    read -rsp $'Press enter to continue...\n'
  • Escape solution (พร้อม -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ระบุโหมด raw ซึ่งไม่อนุญาตให้ใช้อักขระร่วมเช่น "\" หรือ "^"

-sระบุโหมดเงียบและเนื่องจากเราไม่ต้องการเอาต์พุตแป้นพิมพ์

-p $ ' prompt 'ระบุ prompt ซึ่งต้องอยู่ระหว่าง $ 'ถึง' เพื่อให้เว้นวรรคและอักขระที่ใช้ Escape ระวังคุณต้องใส่เครื่องหมายอัญประกาศเดี่ยวกับสัญลักษณ์ดอลลาร์เพื่อรับประโยชน์จากอักขระที่หลีกเลี่ยงมิฉะนั้นคุณสามารถใช้เครื่องหมายคำพูดง่าย ๆ ได้

-d $ ' \ e 'ระบุ escappe เป็นตัวคั่นอักขระดังนั้นเป็นอักขระตัวสุดท้ายสำหรับรายการปัจจุบันนี่เป็นไปได้ที่จะใส่อักขระใด ๆ แต่ต้องระวังใส่อักขระที่ผู้ใช้สามารถพิมพ์ได้

-n 1ระบุว่าต้องการเพียงอักขระเดียวเท่านั้น

-eระบุโหมด readline

-i $ ' Y 'ระบุ Y เป็นข้อความเริ่มต้นในโหมด readline

-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

หนึ่งสามารถทำงานได้รวดเร็วและรวดเร็วดีจริงๆโดยใช้ echo ก่อนอ่านในที่สุด echo -n
THESorcerer

15

readโดยไม่มีพารามิเตอร์ใด ๆ จะดำเนินการต่อถ้าคุณกด Enter pauseคำสั่งDOS จะดำเนินการต่อหากคุณกดปุ่มใด ๆ ใช้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 ...
Stephane Chazelas

@ StephaneChezales ขอบคุณ - ฉันไม่รู้เหมือนกัน ไม่สามารถแก้ไขได้ตอนนี้ ขอขอบคุณอีกครั้ง - คงที่ คุณเป็นข้อมูลที่คุ้มค่าที่สุด
mikeserv

1
นอกจากนี้ยังทราบsettings=$(stty -g); stty raw; dd ...; stty "$settings"ถึงการบันทึกและเรียกคืนการตั้งค่า tty
Stephane Chazelas

@StephaneChezales - ฉันไม่ได้ใช้คอมพิวเตอร์ - คุณคิดว่าtrสิ่งที่แก้ไขสามารถใช้งานได้หรือไม่
mikeserv

1
ไม่เพราะtrจะบัฟเฟอร์เอาต์พุตเป็นไพพ์และคีย์บอร์ดที่ไม่ใช่ของสหรัฐอเมริกามีคีย์ที่ส่งอักขระนอก\1-\177ช่วง ddเป็นวิธีสำนวนที่นี่
Stephane Chazelas

2

หากคุณต้องการหยุดลูปหรือสคริปต์ชั่วคราวและคุณยินดีที่จะกด Enter แทนคีย์ใด ๆ จากนั้นก็readจะทำงานเอง

do_stuff
read
do_more_stuff

มันไม่ได้เป็นมิตรกับผู้ใช้ แต่อาจเพียงพอในกรณีที่คุณเขียนสคริปต์ด่วนสำหรับตัวคุณเองและคุณต้องหยุดมันชั่วคราวเพื่อทำบางสิ่งด้วยตนเองในพื้นหลัง


สิ่งนี้เป็นจริง แต่สำหรับฐานข้อมูลการแสดงตัวอย่างมีประโยชน์มากที่สุด
SDsolar

ขอบคุณฉันรับคำแนะนำของคุณบนกระดาน เพียงแค่เขียนชื่อคำสั่งไม่ชัดเจนในการเข้าใจถึงปัญหาหลังเหตุการณ์
mwfearnley

1

ลองสิ่งนี้:

function pause(){
   read -p "$*"
}

1
ใครช่วยอธิบายหน่อยได้ไหมว่าทำไมเรื่องนี้ถึงถูกลงคะแนน? มันเป็นเพราะการขาดเนื้อหาหรือเป็นทางออกที่ไม่ดี?
3ocene

4
@ 3ocene นี่ไม่แสดงการใช้งานของฟังก์ชั่นที่สร้างขึ้น; รวมถึงการขาดคำอธิบายใด ๆ
parvus

ตกลง คุณช่วยกรุณาแสดงตัวอย่างของการเรียกใช้ฟังก์ชันนี้ได้อย่างไร?
SDsolar

1

ฟังก์ชั่นนี้ใช้งานได้ทั้งbashและzshและทำให้แน่ใจว่า I / O กับเทอร์มินัล:

# 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คือการให้พรอมต์ทุบตีที่ตามมาจะปรากฏในบรรทัดถัดไป

มิฉะนั้นจะแสดงบนบรรทัดเดียวกันโดยตรงหลังจาก "ดำเนินการต่อ ... " เมื่อEnterกดในเทอร์มินัล

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.