it-swarm-ko.tech

bash에서 죽인 후 종료 된 메시지를 억제하는 방법은 무엇입니까?

Bash 스크립트에서 프로세스를 종료 한 후 나타나는 Terminated 메시지를 어떻게 억제 할 수 있습니까?

나는 set +bm,하지만 작동하지 않습니다.

다른 해결책으로 exec 2> /dev/null, 그러나 그것은 믿을만합니까? stderr를 계속 볼 수 있도록 재설정하려면 어떻게합니까?

51
user14437

짧은 대답은 당신이 할 수 없다는 것입니다. Bash는 항상 포 그라운드 작업의 상태를 인쇄합니다. 모니터링 플래그는 백그라운드 작업에만 적용되며 스크립트가 아닌 대화식 쉘에만 적용됩니다.

작업의 notify_of_job_status ()를 참조하십시오 .c.

당신이 말했듯이 표준 오류가/dev/null을 가리 키도록 리디렉션 할 수 있지만 다른 오류 메시지는 누락됩니다. 스크립트를 실행하는 서브 쉘에서 경로 재 지정을 수행하여 임시로 만들 수 있습니다. 이것은 원래 환경을 그대로 둡니다.

(script 2> /dev/null)

이것은 모든 오류 메시지를 잃을 것이지만 해당 쉘에서 실행되는 다른 것이 아니라 해당 스크립트에서만 발생합니다.

새 파일 디스크립터를 재지 정하여 표준 오류를 저장하고 복원 할 수 있습니다.

exec 3>&2          # 3 is now a copy of 2
exec 2> /dev/null  # 2 now points to /dev/null
script             # run script with redirected stderr
exec 2>&3          # restore stderr to saved
exec 3>&-          # close saved version

그러나 나는 이것을 추천하지 않을 것입니다-첫 번째 것의 유일한 단점은 스크립트가 파일 설명자를 변경하면보다 복잡하고 스크립트의 동작을 변경하면서 하위 쉘 호출을 저장한다는 것입니다.


편집 :

보다 적절한 답변 확인 답변 Mark Edgar

16
wnoise

메시지를 끄려면 메시지가 생성 될 때 stderr로 리디렉션해야합니다 . kill 명령은 신호를 보내고 대상 프로세스가 응답하기를 기다리지 않기 때문에 stderr 명령의 kill를 리디렉션하지 않아도됩니다. 좋은. bash 내장 wait 이 목적을 위해 특별히 만들어졌습니다.

가장 최근의 백그라운드 명령을 종료하는 매우 간단한 예는 다음과 같습니다. ( $!에 대해 자세히 알아보십시오. )

kill $!
wait $! 2>/dev/null

killwait 모두 여러 pid를 허용하므로 일괄 처리를 수행 할 수도 있습니다. 다음은 현재 프로세스/스크립트의 모든 백그라운드 프로세스를 종료하는 예입니다.

kill $(jobs -rp)
wait $(jobs -rp) 2>/dev/null

나는 여기에서 bash : 백그라운드 함수 프로세스를 자동으로 종료 에서 이끌어 냈습니다.

121
Mark Edgar

MarcH의 답변 에서 영감을 받았습니다. 나는 kill -INT 그가 약간의 성공과 함께 제안한 것처럼, 나는 그것이 일부 프로세스를 죽이지 않는 것으로 나타났습니다. 다른 신호를 테스트 한 후 메시지없이 SIGPIPE도 종료됩니다.

kill -PIPE

또는 단순히

kill -13
16
Steven Penny

솔루션 : SIGINT 사용 (비 대화식 쉘에서만 작동)

데모:

cat > silent.sh <<"EOF"
sleep 100 &
kill -INT $!
sleep 1
EOF

sh silent.sh

http://thread.gmane.org/gmane.comp.shells.bash.bugs/15798

8
MarcH

disown를 호출하여 현재 쉘 프로세스에서 프로세스를 분리 하시겠습니까?

4

이것이 우리 모두가 찾고있는 것입니까?

원하지 않음 :

$ sleep 3 &
[1] 234
<pressing enter a few times....>
$
$
[1]+  Done                    sleep 3
$

구함 :

$ (set +m; sleep 3 &)
<again, pressing enter several times....>
$
$
$
$
$

보시다시피, 작업 종료 메시지가 없습니다. bash 스크립트에서도 작동하며 백그라운드 프로세스가 종료되었습니다.

'set + m'은 현재 쉘에 대한 작업 제어를 비활성화합니다 ( '도움말 세트'참조). 따라서 서브 쉘에 명령을 입력하면 (여기에서 괄호 안에 표시됨) 현재 쉘의 작업 제어 설정에 영향을 미치지 않습니다. 단점은 종료 여부를 확인하거나 리턴 코드를 평가하려는 경우 백그라운드 프로세스의 pid를 현재 쉘로 다시 가져와야한다는 것입니다.

1
Ralph

이것은 killall에도 적용됩니다 (좋아하는 사람들을 위해).

killall -s SIGINT (yourprogram) 

메시지를 표시하지 않습니다 ... 배경 모드에서 mpg123을 실행 중이었습니다. SIGTERM (기본값) 대신 ctrl-c (SIGINT)를 보내야만 자동으로 종료 될 수 있습니다.

1
Coder of Salvation

작업 알림을 비활성화하는 또 다른 방법은 명령을 sh -c 'cmd &' 구성.

#!/bin/bash
# ...
pid="`sh -c 'sleep 30 & echo ${!}' | head -1`"
kill "$pid"
# ...

# or put several cmds in sh -c '...' construct
sh -c '
sleep 30 &
pid="${!}"
sleep 5 
kill "${pid}"
'
1
phily

단순한:

{ kill $! } 2>/dev/null

이점? 모든 신호를 사용할 수 있습니다

전의:

{ kill -9 $PID } 2>/dev/null
0
user2429558

disown은 정확히 옳은 일을했습니다 .exec 3> & 2는 여러 가지 이유로 위험합니다 .set + bm은 명령 프롬프트에서만 스크립트 내에서 작동하지 않는 것 같습니다.

0
clemep

Kill 명령을 함수에 넣은 다음 함수를 백그라운드로 지정하면 종료 출력이 억제됩니다.

function killCmd() {
    kill $1
}

killCmd $somePID &
0
Al Joslin

스크립트에 'jobs 2>&1 >/dev/null'를 추가하는 데 성공했습니다. 다른 사람의 스크립트에 도움이 될지 확실하지 않지만 여기에 샘플이 있습니다.

    while true; do echo $RANDOM; done | while read line
    do
    echo Random is $line the last jobid is $(jobs -lp)
    jobs 2>&1 >/dev/null
    sleep 3
    done
0
J-o-h-n-