code

작업 및 프로세스 ID를 인쇄하지 않고 백그라운드에서 bash 명령 실행

codestyles 2020. 11. 24. 08:00
반응형

작업 및 프로세스 ID를 인쇄하지 않고 백그라운드에서 bash 명령 실행


bash에서 백그라운드에서 프로세스를 실행하는 것은 매우 쉽습니다.

$ echo "Hello I'm a background task" &
[1] 2076
Hello I'm a background task
[1]+  Done                    echo "Hello I'm a background task"

그러나 출력은 장황합니다. 첫 번째 줄에는 백그라운드 작업의 작업 ID와 프로세스 ID가 인쇄되고 명령의 출력이 표시되고 마지막으로 작업 ID, 작업 상태 및 작업을 트리거 한 명령이 표시됩니다.

마지막에 앰퍼샌드없이 출력이 정확히 표시되도록 백그라운드 작업 실행의 출력을 억제하는 방법이 있습니까? 즉 :

$ echo "Hello I'm a background task" &
Hello I'm a background task

내가 묻는 이유는 탭 완성 명령의 일부로 백그라운드 프로세스를 실행하여 해당 명령의 출력이 의미를 갖도록 중단되지 않아야하기 때문입니다.


완료와는 관련이 없지만 하위 쉘에 호출을 넣어 출력을 억제 할 수 있습니다.

(echo "Hello I'm a background task" &)

일부 최신 버전의 bash 및 ksh93에서는 하위 쉘 또는 프로세스 그룹 (예 :)으로 묶을 수 있습니다 { ... }.

/home/shellter $ { echo "Hello I'm a background task" & } 2>/dev/null
Hello I'm a background task
/home/shellter $

@shellter의 답변을 바탕으로 이것은 나를 위해 일했습니다.

tyler@Tyler-Linux:~$ { echo "Hello I'm a background task" & disown; } 2>/dev/null; sleep .1;
Hello I'm a background task
tyler@Tyler-Linux:~$

나는 그 이유를 모르지만 bash가 프로세스 ID를 출력하는 것을 방지하는 오래된 게시물에서 기억했습니다.


위의 답변을 바탕으로 명령에서 stderr을 허용해야하는 경우 :

f() { echo "Hello I'm a background task" >&2; }
{ f 2>&3 &} 3>&2 2>/dev/null

이 답변을 바탕으로 더 간결하고 정확한 것을 생각해 냈습니다.

silent_background() {
    { 2>&3 "$@"& } 3>&2 2>/dev/null
    disown &>/dev/null  # Prevent whine if job has already completed
}
silent_background date

시험:

user@host:~$ read < <( echo "Hello I'm a background task" & echo $! )
user@host:~$ echo $REPLY
28677

그리고 출력PID를 모두 숨겼습니다 . $ REPLY에서 여전히 PID검색 할 수 있습니다.


이전 게시물에 대한 답변에 대해 죄송하지만 다른 사람에게 유용하다고 생각하며 Google의 첫 번째 답변입니다.

이 방법 (서브 쉘)에 문제가 있고 '대기'를 사용했습니다. 그러나 함수 내에서 실행하면서 다음과 같이 할 수있었습니다.

function a {
    echo "I'm background task $1"
    sleep 5
}

function b {
    for i in {1..10}; do
        a $i &
    done
    wait
} 2>/dev/null

그리고 내가 그것을 실행할 때 :

$ b
I'm background task 1
I'm background task 3
I'm background task 2
I'm background task 4
I'm background task 6
I'm background task 7
I'm background task 5
I'm background task 9
I'm background task 8
I'm background task 10

프롬프트를 다시 받기까지 5 초의 지연이 있습니다.


서브 쉘 솔루션은 작동하지만 백그라운드 작업을 기다릴 수 있기를 원했습니다 (끝에 "Done"메시지가 표시되지 않음). $!현재 대화식 쉘에서 서브 쉘에서 "대기 가능"하지 않습니다. 나를 위해 일한 유일한 해결책은 매우 간단한 자체 대기 기능을 사용하는 것입니다.

myWait() {
  while true; do
    sleep 1; STOP=1
    for p in $*; do
      ps -p $p >/dev/null && STOP=0 && break
    done
    ((STOP==1)) && return 0
  done
}

i=0
((i++)); p[$i]=$(do_whatever1 & echo $!)
((i++)); p[$i]=$(do_whatever2 & echo $!)
..
myWait ${p[*]}

충분히 쉽습니다.

참고 URL : https://stackoverflow.com/questions/7686989/running-bash-commands-in-the-background-without-printing-job-and-process-ids

반응형