스크립트 파일의 TMOUT이 선택 명령에서 제대로 작동하지 않습니다. 어떻게 고치나요?

스크립트 파일의 TMOUT이 선택 명령에서 제대로 작동하지 않습니다. 어떻게 고치나요?

고쳐 쓰다- 이것은 4.3.46에서 잘 작동하므로 bash 4.3.42에만 해당되는 것 같습니다. 나중에 같은 문제가 발생하는 사람을 위해 이 게시물을 저장하겠습니다.

Bash 명령줄에서 이 명령을 실행하면 정상적으로 작동합니다.

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

결과는 보여줍니다선택의 여지가 없다그리고 명령줄로 돌아갑니다.

그런데 스크립트에 넣어서 실행하면 반복적으로 선택을 요청합니다.

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

% ./a.sh

결과:

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

왜 그럴까요? 내 주요 질문은 -스크립트에서 어떻게 작동하게 합니까?

고쳐 쓰다

% 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

답변1

매뉴얼에서:

TMOUT 0보다 큰 값으로 설정되면 TMOUT은 내장 읽기에 대한 기본 시간 제한으로 처리됩니다. 터미널에서 입력이 올 때 TMOUT 초 후에도 입력이 도착하지 않으면 선택 명령이 종료됩니다. 대화형 셸에서 이 값은 기본 프롬프트를 실행한 후 입력을 기다리는 시간(초)으로 해석됩니다. 입력이 도착하지 않으면 Bash는 종료되기 전에 지정된 시간(초) 동안 기다립니다.

따라서 첫 번째 경우는 대화형 셸 때문입니다.

$ 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

이제 스크립트가 있습니다

$ 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

답변2

timeout명령을 사용하십시오 . 이 예는 개선될 수 있지만 요점을 전달합니다. 먼저 bash 내장을 사용하여 trap종료 시 무언가를 실행한 다음 루프를 실행합니다. 다음과 같이 실행됩니다.

#] 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

답변3

그래서 결국 스크립트에 사용할 수 있는 나만의 선택 항목을 작성하게 되었습니다.

# $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]}
  }
}

사용 방법:

select_ 10 a b c

예:

$ ./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

관련 정보