Hoe stop ik een bash-script totdat een gebruiker op Space heeft gedrukt?
Ik zou de vraag graag in mijn script willen hebben
Druk op de spatiebalk om door te gaan of CTRL + C om af te sluiten
en dan zou het script moeten stoppen en wachten tot de spatiebalk wordt ingedrukt.
Opmerkingen
- Dit alles en meer wordt behandeld in deze SO Q & A BTW: Wat is het linux-equivalent naar DOS pauze?
- Zie ook: Pauzeer Shell-script tot Druk op Enter tijdens de lus
- gerelateerd: unix.stackexchange.com/questions/293940/…
Answer
U kunt read
gebruiken:
read -n1 -s -r -p $"Press space to continue...\n" 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
Vervang " "
voor spatie hierboven door ""
voor Enter-toets, $"\t"
voor Tab-toets.
Opmerkingen
- U moet -s toevoegen om het ingedrukte teken niet op de terminal af te drukken. En voeg aan het einde een lijnbreuk toe, of de uitvoer gaat direct door op dezelfde regel als de vraag. Het beste zou zijn:
read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
- Dit script ‘ werkt niet. Ik heb het net getest op Red Hat linux … Het
else
-blok wordt altijd uitgevoerd, zelfs als de spatiebalk wordt ingedrukt. - @robert It ‘ s omdat je ‘ niet
bash
gebruikt. Het werkt als je in plaats daarvanread _
gebruikt, als je een andere shell hebt danbash
. - Moet de
''
bevat een spatie binnenin? - Dit leest van STDIN, wat problemen veroorzaakt gegeven
pipeline | script.sh
Zie dit antwoord voor een oplossing.
Antwoord
De methode besproken in deze SO Q & A is waarschijnlijk de beste kandidaat voor een alternatief voor het pause
gedrag dat u “gewend bent aan Windows wanneer BAT-bestanden aan het doen.
$ read -rsp $"Press any key to continue...\n" -n1 key
Voorbeeld
Hier voer ik het bovenstaande uit en druk ik gewoon op een willekeurige toets, in dit geval de D -sleutel.
$ read -rsp $"Press any key to continue...\n" -n1 key Press any key to continue... $
Referenties
Reacties
- Ik bedoel waarom de
$
voor is de tekenreeks hier:-rsp $'Press
? - @ rubo77 – ah. Dat ‘ is hoe je een letterlijke tekenreeks met speciale tekens kunt maken. Het ‘ heeft de vorm: $ ‘ … ‘
- @ rubo77 – dat ‘ is anders. Dat ‘ een dollarteken is met dubbele aanhalingstekens, ik heb een dollar met enkele aanhalingstekens gebruikt. Verwijder alstublieft die opmerking, deze ‘ is fout.
- Ah, ik begrijp het. Voor het geval je ontsnapte reeksen binnen de prompt-string plaatst. zie wiki.bash-hackers.org/syntax/quoting#ansi_c_like_strings
- @ rubo77 – ja die notatie staat toe dat escape-reeksen worden opgenomen zonder enige extra
echo -e "..."
regels. Het ‘ is veel compacter in die situaties.
Antwoord
Je zou er een functie voor kunnen maken:
pause(){ read -n1 -rsp $"Press any key to continue or Ctrl+C to exit...\n" }
Dan kun je dit overal in je script gebruiken:
pause
Reacties
- als je nieuw bent bij shell scripting – je moet de functie bovenaan je script zetten voordat je hem gebruikt
Antwoord
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"
Dit drukt nu een prompt af zonder een nieuwe regel erop, behandelt CTRL+C
betrouwbaar, roept stty
slechts zo vaak aan als nodig is, en herstelt de controlerende tty naar exact de toestand waarin stty
heeft het gevonden. Kijk in man stty
voor informatie over hoe u expliciet echos, tekens en alles bestuurt.
U kunt ook dit doen:
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
Je zou het kunnen doen met ENTER
, geen [
tests ]
en geen stty
zoals:
sed -n q </dev/tty
Reacties
- Uw twee laatste oplossingen lijken ook goed te werken met
/bin/sh
(bijv. op FreeBSD), niet alleen met bash. - is uw antwoord op SO equivalent, of zelfs beter?
Antwoord
Hier “is een manier die werkt in beide bash
en zsh
, en zorgt voor I / O naar de 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
Zet het in je .{ba,z}shrc
voor Grote Gerechtigheid!
Antwoord
luie liner:
echo "Press any key to continue or Ctrl+C to cancel" read && do_something.sh
het nadeel is dat je de controle verliest als de gebruiker op ctrl + c drukt. Het script zal in dat geval altijd afsluiten met code 130.
Answer
Instellingen IFS
op lege string onderdrukt het standaardgedrag van lezen bij het inkorten van witruimte.
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: We kunnen dit vereenvoudigen door de REPLY-variabele te gebruiken, die niet onderhevig is aan woordsplitsing:
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
Antwoord
Hier “een eenvoudige oplossing van Druk op SPACE om door te gaan (niet ENTER)
read -s -d " "
Dit zal wachten tot je op de spatiebalk drukt. Ja, alleen de spatiebalk, deze zou niet breken als je op enter drukt.