백그라운드에서 작업을 자동으로 시작


12

프로세스를 백그라운드에 넣었을 때와 같이 수행 할 때 알림을받지 않고 백그라운드에서 프로세스를 시작하기 위해 이것을 사용할 수 있다는 것을 알고 있습니다.

(명령 &) &> / dev / null

그러나 이렇게하면 프로세스가 끝나면 트랩 할 수있는 옵션이 제거됩니다 ( trap child_done CHLD).

둘 다 어떻게 가질 수 있습니까?

답변:


5

작업 스풀러 가 도움이 될 수 있습니다.

freshmeat.net 에서와 같이 :

작업 스풀러는 작업 스풀이 차례로 실행되는 Unix 배치 시스템입니다. 한 번에 실행할 작업량은 언제든지 설정할 수 있습니다. 각 시스템의 각 사용자는 자신의 작업 대기열을 가지고 있습니다. 작업은 모든 쉘 / 프로세스에서 올바른 컨텍스트 (인큐의 컨텍스트)로 실행되며 출력 / 결과를 쉽게 볼 수 있습니다. 명령이 많은 RAM, 많은 디스크 사용, 많은 출력을 제공하거나 어떤 이유로 든 동시에 실행하지 않는 것이 더 낫다는 것을 알 때 매우 유용합니다. 최대의 이익을 위해 귀하의 자원이 바쁩니다. 인터페이스는 스크립트에서 쉽게 사용할 수 있습니다.

작업 스풀러는 데비안 , 우분투 및 기타 배포판 에서 사용할 수 있습니다 .

실행할 작업 대기열을 확보하고 원하는대로 출력에 액세스 할 수 있습니다.

예를 들면 다음과 같습니다.

$ tsp sleep 5
0 
$ tsp sleep 5 
1
$ tsp
ID   State      Output               E-Level  Times(r/u/s)   Command [run=1/1]
2    running    /tmp/ts-out.ZWn6Le                           sleep 5
1    finished   /tmp/ts-out.Fhlcle   0        5.00/0.00/0.01 sleep 5

백그라운드에서 많은 작업을 실행하면 확실히 도움이 될 것입니다.

순차적으로 또는 미리 설정된 양의 슬롯에서 실행할 수 있습니다. 작업간에 종속성을 설정할 수도 있습니다 ( task0 이 성공적으로 완료된 경우에만 task1을 실행 하십시오 ).


3

두 가지 방법으로이 작업을 수행합니다 {ba,z}sh.

함수를 사용하여 저장하고의 상태를 복원하는 데 필요로하지 않는 데 도움이 zshmonitor를 사용하여 변수를 setopt local_options.

# Run the command given by "$@" in the background
silent_background() {
  if [[ -n $ZSH_VERSION ]]; then  # zsh:  /superuser//a/1285272/365890
    setopt local_options no_notify no_monitor
    "$@" &
  elif [[ -n $BASH_VERSION ]]; then  # bash: /programming//a/27340076/5353461
    { 2>&3 "$@"& } 3>&2 2>/dev/null
  else  # Unknownness - just background it
    "$@" &
  fi
}

이것을 다음과 같이 사용하십시오 :

trap 'echo child done' CHLD
silent_background sleep 1

예상 child done메시지를 생성합니다 .


희망적인 설명 은 unix.stackexchange.com/q/456549/4778 을 참조하십시오 .
ctrl-alt-delor

2

작업 이 비동기 적으로 시작될 때 이 통지를 보내기 때문에 명령 출력의 경로 재 지정은 관련이없는 것 같습니다 . 보다 정확하게는 작업 제어 와 관련된 쉘 기능 (기능성) 입니다.

여기, "Bash Reference Manual", "Job Control"장, 섹션 1에서 인용 한 내용이 있습니다.

셸은 JOB을 각 파이프 라인과 연결합니다. 현재 실행중인 작업 테이블을 유지하며 jobs명령 과 함께 나열 될 수 있습니다 . Bash는 비동기 적으로 작업을 시작하면 다음과 같은 행을 인쇄합니다.

[1] 25647

이 작업이 작업 번호 1이고이 작업과 연관된 파이프 라인에서 마지막 프로세스의 프로세스 ID가 25647임을 나타냅니다. 단일 파이프 라인의 모든 프로세스는 동일한 작업의 구성원입니다. Bash는 작업 제어의 기초로 JOB 추상화를 사용합니다.

쉘 스크립트는이 알림을 표시하지 않습니다.

$ cat test
#!/bin/bash

true & echo true
$ ./test
true

사실

Zsh

Zsh 문서는 이러한 알림에 대한 유사한 표시를 제공합니다 man 1 zshmisc. "JOBS"섹션을 참조하십시오 . 작업 제어 가 비활성화 되면 이러한 알림이 표시되지 않습니다.

모니터 ( -m , ksh : -m )

    작업 제어를 허용하십시오. 대화식 쉘에서 기본적으로 설정됩니다.

zsh_prompt % setopt no_monitor
zsh_prompt % true & echo true
true
zsh_prompt %
zsh_prompt % 

세게 때리다

Bash는 항상 예를 ​​들어 표시되는 것 같습니다 [1] 25647. 예를 들어 작업 제어 가 비활성화 된 [1]+ Done true경우 "최종 알림" 이 표시되지 않습니다.

bash_prompt $ true & echo true
[1] 25647
true
bash_prompt $ 
[1]+  Done                    true

작업 제어 비활성화

bash_prompt $ set +m       # disable job control
bash_prompt $ true & echo true
[1] 25685
bash_prompt $
bash_prompt $

결론

알림을 숨기려면 작업 제어 를 사용하지 않는 것이 좋은지 모르겠습니다 .

자원


1

zsh작업 알림을 비활성화하기 위해 비 대화식 쉘로 호출 할 수 있습니다 .

zsh -c '
   trap "echo trapped child_done" CHLD
   sleep 5 &
   #wait
   sleep 10 # simulate other running cmds
   echo script done
'

0

다음 예를 참조하십시오.

trap 'echo "DONE"' 0
{ find /usr & } &> /dev/null
wait

잘 작동합니다. 필요 없음 : 필요 ( )없는 서브 쉘을 만듭니다. { }단지 그룹화 명령입니다.


인쇄는 [2] 49591하고 [2] + 49591 exit 1 find /usr, 때 어느 쪽이의 인쇄 없어야합니다!
Tyilo

죄송합니다, 귀하의 질문을 오해했습니다.
Gilles Quenot

0

이것은 오래된 질문이지만 가능한 대답 (bash에서 zsh로 테스트되지 않음)은 서브 쉘에서 작업 제어를 사용하는 것입니다. (command & wait)

참고 : bash는 서브 쉘에서 시작 / 종료 백그라운드 작업 메시지를 억제하므로 경로 재 지정할 필요가 없습니다.


함정에 빠진 부분이 있다고 생각합니다. 하위 프로세스가 시작되어야한다는 질문을 이해하는 한, supprocess가 실행되는 동안 하위 프로세스가 수행 된 다음 하위 프로세스가 완료되면 다른 작업이 실행되어야합니다. 솔루션을 사용하면 서브 프로세스를 시작하여 서브 쉘에서 서브 프로세스를 기다리고 메인 쉘은 서브 쉘을 기다립니다. 이것은 메시지를 제거하지만 병렬로 할 수는 없습니다.
Raphael Ahrens

아니요, (sleep 5 & wait)5 초 지연됩니다.
Tom Hale
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.