TMOUT dentro del archivo de secuencia de comandos se comporta mal para el comando de selección. ¿Como arreglarlo?

TMOUT dentro del archivo de secuencia de comandos se comporta mal para el comando de selección. ¿Como arreglarlo?

ACTUALIZAR- Parece que esto es algo peculiar con bash 4.3.42 ya que funciona bien con 4.3.46. Dejando esta publicación para aquellos que se encuentren con el mismo problema en el futuro.

Cuando ejecuto este comando en la línea de comando bash, funciona correctamente:

% (TMOUT=3; s="no selection"; select s in a b c ; do break ; done; echo $s)
1) a
2) b
3) c
#?
no selection
% _

Resultado: muestraSin seleccióny regresa a la línea de comando.

Sin embargo, cuando le coloco un script y lo ejecuto, solicita selección repetidamente.

% cat a.sh
#!/bin/bash
(TMOUT=3; s="no selection"; select s in a b c ; do break ; done; echo $s)

% ./a.sh

Resultado:

1) a
2) b
3) c
#? 1) a
2) b
3) c
#? 1) a
2) b
3) c
#? ^C
% _

¿Por qué es así? Mi pregunta principal es -¿Cómo hacer que funcione en un script?

ACTUALIZADO

% bash --version
GNU bash, version 4.3.42(1)-release (x86_64-unknown-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.

% uname
Linux lx1 2.6.32-642.6.2.el6.x86_64 #1 SMP Mon Oct 24 10:22:33 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux

Respuesta1

Del manual:

TMOUT Si se establece en un valor mayor que cero, TMOUT se trata como el tiempo de espera predeterminado para la lectura incorporada. El comando de selección finaliza si la entrada no llega después de TMOUT segundos cuando la entrada proviene de un terminal. En un shell interactivo, el valor se interpreta como el número de segundos que se debe esperar la entrada después de emitir el mensaje principal. Bash finaliza después de esperar esa cantidad de segundos si no llega la entrada.

Entonces, el primer caso se debe al shell interactivo.

$ ps -aef|grep bash; echo "before"; (TMOUT=3; s="no selection"; ps -aef|grep bash; select s in a b c ; do break ; done; echo $s;ps -aef|grep bash);echo "after";ps -aef|grep bash
asktyagi    4926 23767  0 09:40 pts/0    00:00:00 grep --color=auto bash
asktyagi   23767 23741  0 09:03 pts/0    00:00:00 -bash
**before**
asktyagi    4927 23767  0 09:40 pts/0    00:00:00 -bash
asktyagi    4929  4927  0 09:40 pts/0    00:00:00 grep --color=auto bash
asktyagi   23767 23741  0 09:03 pts/0    00:00:00 -bash
1) a
2) b
3) c
#?
no selection
asktyagi    4927 23767  0 09:40 pts/0    00:00:00 -bash
asktyagi    4931  4927  0 09:40 pts/0    00:00:00 grep --color=auto bash
asktyagi   23767 23741  0 09:03 pts/0    00:00:00 -bash
**after**
asktyagi    4933 23767  0 09:40 pts/0    00:00:00 grep --color=auto bash
asktyagi   23767 23741  0 09:03 pts/0    00:00:00 -bash

Ahora con guión

$ cat a.sh
#!/bin/bash
(TMOUT=3; s="no selection"; select s in a b c ; do break ; done; echo $s)
ps -aef|grep bash

$ sh a.sh
1) a
2) b
3) c
#?
no selection
asktyagi    5201  5188  0 09:41 pts/0    00:00:00 grep bash
asktyagi   23767 23741  0 09:03 pts/0    00:00:00 -bash

Respuesta2

Utilice el timeoutcomando. Este ejemplo podría mejorarse, pero aclara el punto. Primero use el trapcomando bash-builtin para ejecutar algo al salir, luego ejecute su bucle. Se ejecuta de la siguiente manera:

#] timeout 3s sh -c 'trap "echo no selection" EXIT; select s in a b c ; do break ; done; '
1) a
2) b
3) c
#? <waits 3 seconds>no selection

Respuesta3

Finalmente, escribí mi propia selección que se puede usar en un guión.

# $1 timeout
# rest - selection
function select_ {
  t=$1
  shift
  arr=($*)
  i=1
  for a in $*; do
    echo "$i) $a" >$(tty)
    ((i++))
  done
  echo "TIMEOUT: In ${t} seconds ${arr[0]} will be automatically selected." >$(tty)
  printf "#? " >$(tty)
  read -t $t x
  [ "$x" == "" ] && {
     x=1
     echo "$x" >$(tty)
  }
  ((x=x+0))
  [ "$x" -ge 1 -a "$x" -le ${#arr[@]} ] && {
    ((x--))
    echo ${arr[$x]}
  }
}

Cómo usarlo:

select_ 10 a b c

Ejemplo:

$ ./x.sh
1) a
2) b
3) c
TIMEOUT: In 10 seconds a will be automatically selected.
#? 2
b

$ ./x.sh
1) a
2) b
3) c
TIMEOUT: In 10 seconds a will be automatically selected.
#? 1
a

información relacionada