쉘 스크립트 출력에서 ​​stdout/stderr을 억제하는 방법은 무엇입니까?

쉘 스크립트 출력에서 ​​stdout/stderr을 억제하는 방법은 무엇입니까?

백그라운드에서 실행 중인 프로세스를 중지했다가 다시 시작하는 스크립트가 있습니다.

process_id=`ps -eaf | grep -i daemon | grep -v grep | grep -v status | grep -v stop | awk '{print $2}'`
(kill -STOP $process_id) &
... # do something else 
(kill -CONT $process_id) &

이것은 잘 작동하지만 STDOUT/STDERR에서 다음을 얻습니다.

[1]  +  8545 Suspended (signal)            /etc/init.d/...

지금까지 나는 다음을 시도했습니다.

(kill -STOP $process_id)

(kill -STOP $process_id) & > /dev/null

/etc/init.d/{name_of_the_daemon} start > /dev/null

(kill -STOP $process_id & ) 2>/dev/null 

(kill -STOP $process_id & disown;) 2>/dev/null 

set +m
(kill -STOP $process_id) & 

(kill -STOP $process_id) & 1>&2

제가 수행하는 단계는 다음과 같습니다.

  1. fff 파일 생성/etc/init.d/
  2. 아래 스크립트를 붙여넣으세요.
  3. chmod 755 fff
  4. /etc/init.d/fff 시작

그 후 '일시 중지' 메시지가 표시됩니다.

@sourcejedi에 따르면 내 스크립트는 데몬이 아닙니다. 스크립트의 하위 프로세스가 일시 중지되면 "중지" 메시지가 나타납니다.

셸에 출력되는 특정 메시지만 표시하지 않으려면 어떻게 해야 합니까?

내 스크립트의 매우 간단한 버전은 다음과 같습니다.

#!/bin/bash

pid_script=`ps -eaf | grep -i fff | grep -v grep | grep -v status | grep -v stop | awk '{print $2}'`

case "$1" in
    start)
    ( sleep 3; kill -STOP $pid_script ) &
    sleep 10;
    (sleep 1; kill -CONT $pid_script) &
    ;;
    stop)
    for p in $pid_script # kill all the other processes related with this script (if any)
        do
            kill -9 $p
        done
esac

답변1

이 가 표시되면 [1] + 7766 Suspended (signal) ...이는 하위 프로세스 중 하나가 일시 중지되었음을 알리는 쉘에 의해 인쇄되는 메시지입니다.

이 예 에서는 fff두 가지 셸 프로세스를 고려해야 합니다. 초기 대화형 셸과 하위 프로세스로 실행되는 셸 스크립트입니다.

스크립트가 자체적으로 중단되도록 준비합니다. 대화형 쉘은 "hang" 메시지를 인쇄합니다. 그래서 켜거나 끌 수 있는 옵션이 아닙니다.스크립트 내부.

또한 대화형 셸에서 옵션을 설정하여 이 특정 메시지를 켜거나 끌 수 없습니다. 이 메시지만으로는 "억제"하는 것이 불가능합니다... 기본적으로 그것은 결코 당신이 하고 싶은 일이 아니기 때문입니다 :-).

fff어쨌든 스크립트가 성공적으로 자체 복원될 수 있다고 생각하지 않습니다 . 나는 이것을 달성하기 위해 수정될 수 있다고 생각합니다. 그러나 회복 자체는 나쁜 생각입니다. 스크립트를 일시 중지하면 대화형 셸에 명령 프롬프트가 다시 표시됩니다. 즉, "일시 중지" 메시지가 표시되지 않으면 스크립트가 완료된 것 같습니다. 그러나 어느 쪽이든 스크립트가 자체적으로 복구되면 사용자가 그 동안 무엇을 시작하든 관계없이 사용자로부터 터미널 제어권을 되찾으려고 시도합니다. 아주 좋은하지!


예를 들어 터미널에서 프로세스를 시작했는데 이것이대화형 쉘 하위 프로세스그렇다면 그것은 확실히악마프로세스.

시작하다악마터미널에서 프로그램은 시작하는 동안 자체적으로 fork()해야 합니다. 원래 프로세스가 종료되어야 실행 중인 프로세스가 계속됩니다.재육아예를 들어 (기존 유닉스에서는) PID 1 일명 process 입니다 init. 또한 터미널에서 분리하기 위한 추가 단계도 포함해야 합니다. 여기에서 예를 참조하세요.쉘에서 프로세스를 데몬화합니까?

또한 시스템에서 를 사용하는 경우 부팅하려면 레거시 스크립트를 사용해야 한다는 점을 systemd이해해야 합니다 . 데비안과 다른 곳의 패키징 스크립트에는 이를 수행하는 호환성 핵이 포함되어 있습니다. 하지만 넌 그래야 해/etc/init.d/systemctl startinit.d아니요이 기능을 사용하세요. 이것은 혼돈의 비결입니다. 작성하신 스크립트에는 이 기능이 없으므로~ 해야 하다사용 systemctl start fff.

fff스크립트 의 게임을 systemctl start.

실제로 systemctl백그라운드 서비스 프로세스를 시작하는 데 사용되는 방법은 다양합니다. systemd요청된 프로그램을 시작하는 PID 1(init 프로세스)에 메시지를 보냅니다 . 기본 시스템 서비스를 정의하는 경우 프로그램은 데몬 자체를 필요로 하지 않습니다. 이전 스크립트를 사용하는 경우 init.d프로그램은 여전히 ​​자체 데몬화해야 하지만 프로그램이 수행하는 유일한 작업은 systemd스크립트 init.d시작이 완료되었음을 알리는 것뿐입니다. (이렇게 하면 데몬에서 일부 시작 실패를 확인할 수 있지만 불행하게도 많은 기존 프로그램이 데몬 단계 후에 시작 실패를 겪을 수 있습니다.)

스크립트 가 자체적으로 중지하고 다시 시작하는 데 스크립트 systemd가 반응하는지 여부와 어떻게 반응하는지 걱정하고 싶지 않습니다 .init.d

답변2

귀하의 목표를 올바르게 이해하고 있는지 확실하지 않지만 이것은 나에게 효과적입니다.

  1. 실제로 지속적으로 실행되는 프로세스인 "데몬"을 시작합니다.top -d1 >out

  2. tail -f out원하시면 두 번째 터미널에서

  3. 세 번째 터미널에서 나는 달린다kill -STOP $(ps -eFH | grep "top -d" |grep -v grep|awk '{print $2}'

데몬을 시작한 첫 번째 터미널에 "hang" 메시지가 표시되지만 out파일에는 그러한 메시지가 없습니다.

관련 정보