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
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
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.
read -n1 -rsp $'Press any key to continue or Ctrl+C to exit...\n'
else
blocket körs alltid, även när du trycker på mellanslagstangenten.bash
. Det fungerar om du använderread _
istället, om du har något annat skal änbash
.''
innehåller ett mellanslag inuti?pipeline | script.sh
Se detta svar för en lösning.