Tryck på mellanslag för att fortsätta

Hur stoppar jag ett bash-skript tills en användare har tryckt på Mellanslag ?

Jag vill ha frågan i mitt skript

Tryck på mellanslag för att fortsätta eller CTRL + C för att avsluta

och sedan ska skriptet stoppa och vänta tills Space trycks ned.

Kommentarer

  • Allt detta och mer behandlas i denna SO Q & A BTW: Vad är Linux-ekvivalenten till DOS-paus?
  • Se även: Pausa skalskriptet tills du trycker på Enter i medan loop
  • relaterat: unix.stackexchange.com/questions/293940/…
  • Svar

    Du kan använda read:

    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 

    Ersätt " " för utrymmet ovan med "" för Enter-tangent, $"\t" för Tab-tangent.

    Kommentarer

    • Du bör lägga till -s för att inte skriva ut det pressade tecknet på terminalen. Och lägg till en linebreak i slutet, eller så fortsätter produktionen direkt i samma rad som i frågan. Bäst skulle vara: read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
    • Detta skript fungerar inte ’ t. Testade det precis på Red Hat linux … else blocket körs alltid, även när du trycker på mellanslagstangenten.
    • @robert It ’ beror på att du inte använder ’ bash. Det fungerar om du använder read _ istället, om du har något annat skal än bash.
    • Skulle '' innehåller ett mellanslag inuti?
    • Detta läser från STDIN, vilket kommer att orsaka problem som ges pipeline | script.sh Se detta svar för en lösning.

    Svara

    Metoden diskuteras i denna SO Q & A är troligen den bästa kandidaten för ett alternativ till pause beteende som du är van vid på Windows när gör BAT-filer.

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

    Exempel

    Här kör jag ovanstående och trycker sedan helt enkelt på valfri tangent, i det här fallet D -tangent.

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

    Referenser

    Kommentarer

    • Jag menar varför $ befo åter strängen här: -rsp $'Press?
    • @ rubo77 – ah. Att ’ är hur du kan göra en bokstavlig sträng med specialtecken. Det ’ s av formen: $ ’ … ’
    • @ rubo77 – att ’ är annorlunda. Att ’ är ett dollartecken med dubbla citat, jag använde en dollar med enkla citat. Ta bort den kommentaren, den är ’ fel.
    • Ah, jag förstår. Om du placerar räddade sekvenser i snabbsträngen. se wiki.bash-hackers.org/syntax/quoting#ansi_c_like_strings
    • @ rubo77 – ja att notationen tillåter att escape-sekvenser ingår utan extra echo -e "..." rader. Det ’ är mycket mer kompakt i dessa situationer.

    Svar

    Du kan skapa en funktion för den:

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

    Då kan du använda den överallt i ditt skript:

    pause 

    Kommentarer

    • om du är ny på att skripta skript – måste du placera funktionen högst upp i ditt skript innan du använder det

    Svar

    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" 

    Detta skriver nu ut en uppmaning utan en efterföljande ny rad, hanterar CTRL+C pålitligt, åberopar stty bara så ofta som nödvändigt och återställer den kontrollerande ttyen till exakt det tillstånd där stty hittade det. Titta på man stty för information om hur man uttryckligen styr ekon, kontrolltecken och allt.

    Du kan också göra detta:

    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 

    Du kan göra det med ENTER, ingen [ tester ] och ingen stty som:

    sed -n q </dev/tty 

    Kommentarer

    • Dina två sista lösningar verkar fungera bra med /bin/sh (t.ex. på FreeBSD), inte bara med bash.
    • är ditt svar på SO motsvarande, eller ännu bättre?

    Svar

    Här ”på ett sätt som fungerar i båda bash och zsh, och säkerställer I / O till terminalen:

    # 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 

    Lägg det i ditt .{ba,z}shrc för stor rättvisa!

    Svar

    lazy one liner:

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

    nackdelen är att du tappar kontrollen när användaren trycker på ctrl + c. Skriptet kommer alltid att avslutas med kod 130 i så fall.

    Svara

    Inställningar IFS till tom sträng undertrycker läsens standardbeteende för att trimma vitt utrymme.

    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 

    UPPDATERING 2018-05-23: Vi kan förenkla detta med variabeln SVAR, som inte är föremål för orduppdelning:

    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 

    Svar

    Här ”är en enkel lösning från Tryck på MELLANSLAG för att fortsätta (inte ENTER)

    read -s -d " "

    Detta väntar tills du trycker på mellanslagstangenten. Ja, bara mellanslagstangenten, den skulle inte gå sönder om du trycker på enter.

    Lämna ett svar

    Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *