bash : 백그라운드 함수 프로세스를 조용히 종료
쉘 전문가,
foo()
지루하고 긴 명령에 대한 진행률 표시 줄을 표시하기 위해 백그라운드 함수 (예 :)를 시작하는 bash 셸 스크립트 가 있습니다.
foo()
{
while [ 1 ]
do
#massively cool progress bar display code
sleep 1
done
}
foo &
foo_pid=$!
boring_and_long_command
kill $foo_pid >/dev/null 2>&1
sleep 10
이제 foo
죽으면 다음 텍스트가 표시됩니다.
/home/user/script: line XXX: 30290 Killed foo
이것은 내, 그렇지 않으면 엄청나게 멋진 진행 표시 줄 디스플레이의 굉장함을 완전히 파괴합니다.
이 메시지를 어떻게 제거합니까?
kill $foo_pid
wait $foo_pid 2>/dev/null
BTW, 엄청나게 멋진 진행률 표시 줄에 대해 모르겠지만 Pipe Viewer (pv)를 보셨습니까? http://www.ivarch.com/programs/pv.shtml
이 문제를 직접 알게되었고 "거부"가 우리가 찾고있는 것임을 깨달았습니다.
foo &
foo_pid=$!
disown
boring_and_long_command
kill $foo_pid
sleep 10
프로세스가 여전히 감시 된 "작업"의 쉘 목록에 있기 때문에 사망 메시지가 인쇄됩니다. disown 명령은이 목록에서 가장 최근에 생성 된 프로세스를 제거하므로 SIGKILL (-9)을 사용해도 종료시 디버그 메시지가 생성되지 않습니다.
줄 kill $foo_pid >/dev/null 2>&1
을 다음 줄로 바꾸십시오 .
(kill $foo_pid 2>&1) >/dev/null
업데이트 :
이 답변은 @ mklement0의 의견에 설명 된 이유로 올바르지 않습니다.
이 답변이 백그라운드 작업에 효과적이지 않은 이유는 kill 명령이 완료된 후 Bash 자체가 종료 된 작업에 대한 상태 메시지를 비동기 적으로 출력하기 때문입니다. 이는 허용 된 답변에서와 같이 wait를 사용하지 않는 한 직접 억제 할 수 없습니다.
이것은 비슷한 문제에 대해 생각해 낸 해결책입니다 (장기 실행 프로세스 중에 타임 스탬프를 표시하고 싶음). 이것은 pid를 알고있는 한 조용히 서브 쉘을 죽일 수있는 killsub 함수를 구현합니다. 트랩 명령은 다음을 포함하는 것이 중요합니다. 스크립트가 중단 된 경우 서브 쉘이 계속 실행되지 않습니다.
foo()
{
while [ 1 ]
do
#massively cool progress bar display code
sleep 1
done
}
#Kills the sub process quietly
function killsub()
{
kill -9 ${1} 2>/dev/null
wait ${1} 2>/dev/null
}
foo &
foo_pid=$!
#Add a trap incase of unexpected interruptions
trap 'killsub ${foo_pid}; exit' INT TERM EXIT
boring_and_long_command
#Kill foo after finished
killsub ${foo_pid}
#Reset trap
trap - INT TERM EXIT
이 "해킹"이 작동하는 것 같습니다.
# Some trickery to hide killed message
exec 3>&2 # 3 is now a copy of 2
exec 2> /dev/null # 2 now points to /dev/null
kill $foo_pid >/dev/null 2>&1
sleep 1 # sleep to wait for process to die
exec 2>&3 # restore stderr to saved
exec 3>&- # close saved version
여기 에서 영감을 얻었습니다 . 세계 질서가 회복되었습니다.
함수 시작 부분에 추가 :
trap 'exit 0' TERM
이를 수행하는 또 다른 방법 :
func_terminate_service(){
[[ "$(pidof ${1})" ]] && killall ${1}
sleep 2
[[ "$(pidof ${1})" ]] && kill -9 "$(pidof ${1})"
}
그것을 부르다
func_terminate_service "firefox"
작업 알림을 비활성화하는 또 다른 방법은 명령을 sh -c 'cmd &'
구성에 배경 화하는 것 입니다.
#!/bin/bash
foo()
{
while [ 1 ]
do
sleep 1
done
}
#foo &
#foo_pid=$!
export -f foo
foo_pid=`sh -c 'foo & echo ${!}' | head -1`
# if shell does not support exporting functions (export -f foo)
#arg1='foo() { while [ 1 ]; do sleep 1; done; }'
#foo_pid=`sh -c 'eval "$1"; foo & echo ${!}' _ "$arg1" | head -1`
sleep 3
echo kill ${foo_pid}
kill ${foo_pid}
sleep 3
exit
그것을 set +m
억제하기 위해 before를 사용할 수 있습니다 . 여기 에 대한 자세한 정보
ReferenceURL : https://stackoverflow.com/questions/5719030/bash-silently-kill-background-function-process
'program story' 카테고리의 다른 글
System.Net.Mail을 사용하여 Gmail을 통해 이메일 보내기 (0) | 2021.01.07 |
---|---|
딕셔너리 목록과의 딕셔너리 목록 (0) | 2021.01.07 |
Uri에 대한 Android URL (0) | 2021.01.07 |
Python을 사용하여 RGB 색상을 'green'과 같은 영어 색상 이름으로 변환 (0) | 2021.01.07 |
Unit과 Nothing의 차이점은 무엇입니까? (0) | 2021.01.07 |