3

I have this script start.sh

 #!/bin/bash
while[1]
do 
read -sn3 key
if [$key=="\033[[A"]
then
  ./test1
else
  ./test2
fi
done

I want to set up a forever loop check see if F1 key pressed. If pressed execute test1 else test2. I did start.sh & running in background so other programs can run.

I got error while [1] command not found syntax error near unexpected token 'do' [f==\033]: command not found

Also where is this read command located? I type which read, it didn't find it.

Also, if try ./start.sh & it gives totally different behavior. I enter a key and it says that key is not found. I though & just run the script at background

lilzz
  • 5,243
  • 14
  • 59
  • 87
  • your shebang is broken, did you mean `#!/bin/bash`? If you are using bash, read `help while` for correct syntax or see http://stackoverflow.com/questions/10797835/while-vs-while-true – Fredrik Pihl Feb 23 '14 at 22:32
  • Does it have to be F1? It would be way easier with non-escaped keys like y/n, 1/2, a/b – that other guy Feb 23 '14 at 23:37
  • Yes, F1 will not work if it is caught by the termimal. Eg for XFCE Terminal, F! brings up help. If this is the case, you will have to disable this so that it is passed through to the `pts` device. – Graeme Feb 24 '14 at 00:21

3 Answers3

1

There are several basic syntax problems in your code (consider using shellcheck before posting to clean up these things), but the approach itself is flawed. Hitting "q" and "F1" produces different length inputs.

Here's a script relying on the fact that escape sequences all come in the same read call, which is dirty but effective:

#!/bin/bash
readkey() {
  local key settings
  settings=$(stty -g)             # save terminal settings
  stty -icanon -echo min 0        # disable buffering/echo, allow read to poll
  dd count=1 > /dev/null 2>&1     # Throw away anything currently in the buffer
  stty min 1                      # Don't allow read to poll anymore
  key=$(dd count=1 2> /dev/null)  # do a single read(2) call
  stty "$settings"                # restore terminal settings
  printf "%s" "$key"
}

# Get the F1 key sequence from termcap, fall back on Linux console
# TERM has to be set correctly for this to work. 
f1=$(tput kf1) || f1=$'\033[[A' 

while true
do
  echo "Hit F1 to party, or any other key to continue"
  key=$(readkey)
  if [[ $key == "$f1" ]]
  then
    echo "Party!"
  else
    echo "Continuing..."
  fi
done
that other guy
  • 116,971
  • 11
  • 170
  • 194
  • Nice! Probably better to default to `xterm` escape sequences rather than linux or check `TERM` yourself. It should be more reliably set for the Linux console than the array various of terminal emulators. – Graeme Feb 24 '14 at 00:31
  • @Graeme The question's code uses the Linux console sequence, so chances are that's what their terminal uses. – that other guy Feb 24 '14 at 00:52
0

Should be

while :

or

while true
Zombo
  • 1
  • 62
  • 391
  • 407
0

Try this:

#!/bin/bash

while true
do 
  read -sn3 key
  if [ "$key" = "$(tput kf1)" ]
  then
    ./test1
  else
    ./test2
  fi
done

It is more robust to use tput to generate the control sequence, you can see a full list in man terminfo. If tput isn't available, you can use $'\eOP' for most terminal emulators or $'\e[[A' for the Linux console (the $ is necessary with the string to make bash interpret escape sequences).

read is a bash builtin command - try help read.

Graeme
  • 2,971
  • 21
  • 26
  • @lilzz `tput` is a command that uses the `terminfo` library to generate control sequences. The idea is that it can work with a variety of different terminals, it is in the `ncurses-bin` package on Debian/Ubuntu. If you don't have it, you can use the control sequences here - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html – Graeme Feb 23 '14 at 23:04
  • Also the `$()` is command substitution, it is a way to use the `stdout` of one command in another. – Graeme Feb 23 '14 at 23:06