쉘 스크립트를 일시 중지하려면 아무 키나 누르십시오. 다시 시작하려면 다시 누르십시오.


11

파일을 복사하고 각 파일마다 진행 상황을 반영하는 API 테스트를 위해 쉘 스크립트를 작성했습니다.

각 사본 사이에 2 초의 절전 모드가 있으므로 아무 키나 눌러 스크립트를 일시 중지하여 더 깊이 테스트 할 수있는 기능을 추가하고 싶습니다. 그런 다음 아무 키나 눌러 다시 시작하십시오.

가능한 한 적은 수의 줄에 이것을 어떻게 추가 할 수 있습니까?

답변:


12

스크립트에 무언가를 추가 할 필요가 없습니다. 쉘은 그러한 기능을 허용합니다.

  • 터미널에서 스크립트를 시작하십시오.
  • 동안 실행하고 터미널 사용을 차단한다 ctrl- z. 터미널이 다시 해제되고 프로세스가 중지되었다는 메시지가 표시됩니다. (이제 pocess 상태에 T있고 중지되었습니다)
  • 이제 원하는대로하십시오. 다른 프로세스 / 스크립트를 시작하고 ctrl-로 중지 할 수도 있습니다 z.
  • jobs터미널을 입력 하거나 중지 된 모든 작업을 나열하십시오.
  • 스크립트를 계속하려면 fg(전경)을 입력하십시오 . 작업을 포 그라운드 프로세스 그룹으로 다시 시작하고 작업이 계속 실행됩니다.

예를보십시오 :

root@host:~$ sleep 10 # sleep for 10 seconds
^Z
[1]+  Stopped                 sleep 10
root@host:~$ jobs # list all stopped jobs
[1]+  Stopped                 sleep 10
root@host:~$ fg # continue the job
sleep 10
root@host:~$ # job has finished

당신이 말했듯이, 달리고 sleep 10; notify-send helloCTRL + Z를 눌러 멈 추면 notify-send hello실행됩니다. 두 번째 명령이 실행되면 첫 번째 프로세스가 어떻게 중지됩니까? 그 후 fg내가 타입을 볼 수 없다면 , 두 번째 명령이 이미 실행되었으므로 명백하다.
Edward Torvalds

두 명령이 분리되어 있기 때문에 @edwardtorvalds. 스크립트에서 그들은 하위 쉘에 있어야했습니다. 간단한 스크립트로 작성하고 스크립트를 실행하십시오. 그런 다음 ctrl-z를 중지하면 첫 번째 명령이 완료 될 때까지 두 번째 명령이 실행되지 않습니다. 글쓰기 cmd; cmd; cmd;는 글쓰기 와 같습니다 cmd <newline> cmd <newline> .... 대안으로 여러분이 작성할 수있는 스크립트는 스크립트 ( cmd; cmd; cmd; )처럼 작동 할 것입니다.(
chaos

나는 또한 시도했다 sleep 10. 3 초 후에 CTRL + Z를 누르고 몇 초 후에 다시 시작한 후 수면 명령이 7 초 이내에 죽었다는 것을 알았습니다. 명령이 멈추지 않기 때문에 백그라운드에서 실행됩니다.
Edward Torvalds

@ edwardtorvalds 나도 알아 냈습니다 ... 이해가되지 않습니다. 저는 strace는 D sleep명령을 사용 된 시스템 호출 인 것을 알아 냈다 nanosleep(). 시스템 콜의 정의 된 행동 인 것 같습니다 nanosleep. restart_syscall()이미 경과 한 시간 (신호에 의해 프로세스가 중지 된 시간 포함)을 고려하여 적절히 조정 된 시간 인수를 사용하여 인터럽트 된 시스템 호출을 다시 시작합니다. 맨 페이지를 읽으십시오 : man7.org/linux/man-pages/man2/restart_syscall.2.html
chaos

@chaos 답변을 완료하기위한 몇 가지 메모 (자유롭게 포함하십시오) : ctrl-Z를 수행하면 작업이 일시 중지 ( "중지")되므로 현재 실행 중이 아니므로 계속하기로 결정할 때까지 기다리십시오. : 전경 (예에서 fg %1또는 배경) (예 : bg %1). (예시 혼돈에서 보여준 것처럼, 작업이 1 개의 숫자, 즉 1 개의 정지 된 프로세스 만 제공하는 경우 : 단지 [1]+ stopped sleep 10, %n파트를 생략 할 수 있습니다 . 여러 백그라운드 프로세스 (실행 또는 중지)가있는 경우 원하는 프로세스를 지정해야합니다. with : %n(예 : fg %2 포 그라운드에서 % 2의 이력서를 가지려면)
Olivier Dulac

6

스크립트 안에 남아있는 동안 스크립트를 일시 중지하려면 절전 모드 대신 읽기를 사용할 수 있습니다.

당신이 사용할 수있는

read -t
read -n읽기가 한 문자를 읽을 수 있는 시간 초과를 설정하려면 (실제로 아무 키나 누름) 스크립트를 계속하십시오

코드를 제공하지 않았으므로 다음은 코드 사용 방법의 예입니다.
q를 누르면 read -n1키를 누를 때까지 스크립트가 계속 진행되지 않습니다.
키를 누르면 확인이 재설정되고 스크립트는 정상적으로 루프에서 계속됩니다.

while [[ true ]]; do
    read -t2 -n1 check
    if [[ $check == "q" ]];then
        echo "pressed"
        read -n1
        check=""
    else
        echo "not pressed"
    fi
echo "Doing Something"
done

입력이 화면 출력을 엉망으로 만들지 않도록 stty -echo섹션의 시작과 stty echo끝에 추가 할 수도 있습니다.


@ mikeserv 나는 op가 읽은 것을 신경 쓰지 않는다고 생각합니다. 단지 스크립트를 일시 중지하고 다시 시작하고 싶습니다. 터미널 설정도 저장한다는 것은 무엇을 의미합니까?

1
@ mikeserv ahh 맞아, 나는 단지 모든 stdin이 사용자로부터 올 것이라고 가정하고 있었다.

1

함께 dd하면 안정적으로 파일로부터 1 바이트를 읽을 수 있습니다. 을 사용 stty하면 min터미널 읽기 및 time10 분의 1 초의 출력 을 규정 할 바이트 수를 설정할 수 있습니다 . 이 두 가지를 결합하면 sleep완전히 없이 할 수 있다고 생각합니다. 단말기의 읽기 시간 초과가 작업을 수행하도록하십시오.

s=$(stty -g </dev/tty)
(while stty raw -echo isig time 20 min 0;test -z "$(
dd bs=1 count=1 2>/dev/null; stty "$s")" || (exec sh)
do echo "$SECONDS:" do your stuff here maybe                             
   echo  no sleep necessary, I think                                                          
   [ "$((i+=1))" -gt 10 ] && exit                                                             
done       
) </dev/tty

그것은 while당신이 시험해보기 위해 조롱 한 작은 예제 루프입니다. 2 초마다는 dd그 시도의 읽기에 시간이 초과 stdin에서 재 - /dev/tty- 그리고 while루프 루프. 즉, 또는 dd 하지 않습니다 타임 아웃 당신이 키를 누릅니다 때문에 -이 경우 대화 형 쉘이 호출됩니다.

테스트 실행은 다음과 같습니다. 각 행의 헤드에 인쇄 된 숫자는 쉘 변수의 값입니다 $SECONDS.

273315: do your stuff here maybe
no sleep necessary, I think
273317: do your stuff here maybe
no sleep necessary, I think
273319: do your stuff here maybe
no sleep necessary, I think
273321: do your stuff here maybe
no sleep necessary, I think
sh-4.3$ : if you press a key you get an interactive shell
sh-4.3$ : this example loop quits after ten iterations
sh-4.3$ : or if this shell exits with a non-zero exit status
sh-4.3$ : and speaking of which, to do so you just...
sh-4.3$ exit
exit
273385: do your stuff here maybe
no sleep necessary, I think
273387: do your stuff here maybe
no sleep necessary, I think
273389: do your stuff here maybe
no sleep necessary, I think
273391: do your stuff here maybe
no sleep necessary, I think
273393: do your stuff here maybe
no sleep necessary, I think
273395: do your stuff here maybe
no sleep necessary, I think
273397: do your stuff here maybe
no sleep necessary, I think

stty sanestty 설정을 변경 한 후에는 사용 하지 않아야합니다. 잘못되었지만 어디에서나 재설정 한 것처럼 보이지 않습니까?

@Jidder-아니오 스크립트 상단에 터미널의 상태를 저장합니다 s=$(stty -g </dev/tty). 전화 한 후 즉시 dd로 복원하십시오 stty "$s". 터미널 상태는 서브 쉘에 신경 쓰지 않으므로 이러한 설정은 부모 쉘에 관계없이 고정됩니다. stty sane반드시 당신이하고 싶은 일이 아닙니다-상태가 sane그 시점 에 있다고 가정하는 것보다 상태를 찾은 방식으로 복원하는 것이 좋습니다 . 내가 그것을 복원하지 않았다면 그 echos는 도처에있을 것입니다. 내가 늦게 온 이유를 부분적으로 알아 낸 것입니다. 테스트를 시작할 때 귀하의 답변이 여기에 없었습니다.
mikeserv
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.