백그라운드 프로세스가 끝날 때까지 함수가 반환되지 않는 이유는 무엇입니까?


21

이 스크립트를 고려하십시오.

#!/bin/bash
function start {
  leafpad &
  echo $!
}
PID=$(start)
echo "PID is $PID"

스크립트는 백그라운드 프로세스 인 경우에도 리프 패드 프로세스가 종료 될 때까지 닫는 중괄호를지나 계속 진행되지 않습니다.

왜 이런거야? 함수에서 백그라운드 프로세스를 시작할 수 있습니까?

답변:


22

백그라운드 작업을 작성했지만 여전히 stdout fd가 열려 있기 때문에 함수가 리턴하지만 명령 대체가 차단됩니다. >/dev/null앞에 추가하여 닫으십시오 &.

#!/bin/bash
function start {
  leafpad >/dev/null &
  echo $!
}
PID=$(start)
echo "PID is $PID"

프로세스가 stdin, stdout, stderr을 닫으려면 다음을 사용하십시오.

leafpad >/dev/null 0>&1 2>&1 &

stdin (0), stdout (1) 및 stderr (2)가 닫히고 백그라운드 (&)가 닫힙니다. 또한 이러한 스트림 재 지정을 사용할 때 "지연"된 것을 잊지 마십시오. 즉, 실행 순서대로 복제됩니다.

1>/dev/null 2>&1

2>&1 1>/dev/null

동일하지 않습니다! 전자에서는 스트림을 / dev / null (원하는 것)로 복제하고, 후자에서는 / dev / stdout을 stderr에 복제 한 다음 stdout을 닫습니다. 전송 된 모든 메시지 stderr가 콘솔에 나타납니다.


내 시스템에서 확인 됨
user120161

10
스트림을 닫지 않고 리디렉션합니다.
dcat

4
닫는; 파일 디스크립터는 n>&-어디에 있습니까 n?
dcat

1
@dcat : 그렇습니다. 그러나 /dev/null프로세스가 stdout을 쓰려고 할 때 /에서 / 로의 경로 재 지정으로 인해 i / o 오류가 발생하지는 않지만 1유효하지 않은 FD입니다. 따라서 게시물의 용어는 실제 bash 프로그래밍이 아니라 잘못되었습니다. (실제로, FD 1을 0으로 복제한다는 것은 stdin O_RDONLY이로 열린 파일 디스크립터가됨을 의미하며 , 프로세스를 읽으려고 할 때 (원하는 바이트 수가 아닌) 오류가 발생합니다.) wc >/dev/null 0>&1--–wc: standard input: Bad file descriptor
Peter Cordes

1
@PeterCordes-기존 디스크립터를 닫고 새 디스크립터를 리디렉션하는 것은 상호 배타적 일 필요는 없습니다. exec <&- >&- <>/dev/null >&0stdin / out을 철저하게 처리합니다. 그것은에서 차이가 zsh적어도되는 것입니다 종류 CONCATENATE의 모든 multios가 설정되어 자동으로 동일한 기술자에 열립니다.
mikeserv
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.