터미널에서 프로세스를 완전히 분리하려면 어떻게합니까?


304

우분투에서 Tilda (드롭 다운 터미널)를 "명령 센터"로 사용합니다. 다른 사람들이 그놈 Do, Quicksilver 또는 Launchy를 사용하는 방식과 거의 같습니다.

그러나 프로세스가 시작된 터미널에서 프로세스 (예 : Firefox)를 완전히 분리하는 방법에 어려움을 겪고 있습니다.

  • 발신 단말기를 닫을 때 종료
  • STDOUT / STDERR을 통해 시작 터미널을 "오염"

예를 들어, "적절한"터미널 창에서 Vim을 시작하기 위해 다음과 같은 간단한 스크립트를 시도했습니다.

exec gnome-terminal -e "vim $@" &> /dev/null &

그러나 여전히 오염이 발생합니다 (파일 이름을 전달해도 작동하지 않는 것 같습니다).


1
그것도 좋은 질문입니다. 나는 Bash를 프로그래밍 언어로 간주하는 것이 공정하다고 생각한다. 실제로이 질문의 범위는 아마도 sysadmin쪽에 더있을 것이다.



유스 케이스에는 완전한 분리가 설명되어 있지 않습니다.
jiggunjer

답변:


344

가장 먼저; 당신이 과정을 시작하고 나면, 먼저 (히트를 중지하여 배경을 수 Ctrl- Z다음 입력) bg백그라운드에서 다시 시작할 수 있도록. 이제는 "작업"이고 그 stdout/ stderr/ stdin는 여전히 터미널에 연결되어 있습니다.

프로세스의 끝에 "&"를 추가하여 백그라운드에서 프로세스를 즉시 시작할 수 있습니다.

firefox &

무음 백그라운드에서 실행하려면 다음을 사용하십시오.

firefox </dev/null &>/dev/null &

추가 정보 :

nohup는 stdout / stderr을 파일로 대신 보낼 수 있고 부모 스크립트를 닫으면 자식을 SIGHUP하지 않도록 응용 프로그램을 실행 하는 사용할 수있는 프로그램 입니다. 그러나 응용 프로그램을 시작하기 전에이를 사용했음을 예측해야합니다. nohup작동 방식으로 인해 실행중인 프로세스 에만 적용 할 수 없습니다 .

disown쉘의 작업 목록에서 쉘 작업을 제거하는 bash 내장입니다. 이것이 기본적으로 의미하는 것은 당신이 사용할 수 없다는 것입니다 fg, bg더 이상에,하지만 더 중요한 것은, 당신이 당신의 쉘을 닫을 때 정지 또는 전송하지 않습니다 SIGHUP더 이상 그 아이에게. 달리 nohup, disown사용 프로세스가 시작하고 백그라운드로하고있다.

수없는 것은 프로세스를 시작한 후 프로세스의 stdout / stderr / stdin을 변경하는 것입니다. 적어도 껍질에서 아닙니다. 프로세스를 시작하고 stdout이 터미널 (기본적으로 수행하는 작업)임을 알려 주면 해당 프로세스는 터미널로 출력되도록 구성됩니다. 쉘은 프로세스의 FD 설정과 관련이 없으며 프로세스 자체가 관리하는 것입니다. 프로세스 자체는 stdout / stderr / stdin을 닫을 지 여부를 결정할 수 있지만 쉘을 사용하여 강제로 닫을 수는 없습니다.

백그라운드 프로세스의 출력을 관리하기 위해 "nohup"이 가장 먼저 떠오를 수있는 스크립트 옵션이 많이 있습니다. 그러나 대화 형 프로세스의 경우 시작하지만 침묵하는 것을 잊었습니다 ( firefox < /dev/null &>/dev/null &), 실제로 많은 것을 할 수는 없습니다.

GNU를 얻는 것이 좋습니다 screen. 화면을 사용하면 프로세스 출력이 귀찮게 될 때 실행중인 쉘을 닫고 새로운 것을 열 수 있습니다 ( ^Ac).


아, 그런데 " $@"를 사용하는 곳에서는 사용하지 마십시오 .

$@의미 $1, $2, $3...,에 명령을 설정합니다 :

gnome-terminal -e "vim $1" "$2" "$3" ...

-e는 하나의 인수 만 취하므로 원하는 것은 아닐 것 입니다. $1스크립트가 하나의 인수 만 처리 할 수 ​​있음을 나타내는 데 사용하십시오 .

쉘 명령 문자열 인 하나의 인수 만 취 gnome-terminal -e하므로 -e주어진 시나리오에서 여러 인수가 올바르게 작동하는 것은 실제로 어렵습니다 . 인수를 하나로 인코딩해야합니다. 가장 강력하고 단호하지만 최선의 방법은 다음과 같습니다.

gnome-terminal -e "vim $(printf "%q " "$@")"

고마워요! 슬프게도 하나의 대답 만 받아 들일 수 있습니다. "nohup $ @ &> / dev / null &"및 "alias wvim = 'launch.sh gnome-terminal -x vim'"

20
환상적이고 상세하고 유익한 답변입니다. +1
Teekin

1
@ Hi-Angel 대화식 bash 쉘을 닫으면 bash는 모든 활성 작업을 HUP합니다. 프로세스를 ^ Z 및 bg 할 때 여전히 작업입니다. 백그라운드 작업입니다. 작업으로 제거하려면을 사용 disown하면 bash가 더 이상 HUP하지 않으므로 쉘을 닫은 후에 프로세스가 계속 작동합니다.
lhunath

3
이미 별도의 문자열 문제를 해결하는 $*대신 사용 하지 $@않습니까?
sjas

2
할 수없는 것은 프로세스를 시작한 후 프로세스의 stdout / stderr / stdin을 변경하는 것입니다. -사실이 아닙니다. reptyr이것을 위해 사용하십시오 .
Stefan Seidel

198
nohup cmd &

nohup 프로세스를 완전히 분리 (데몬 화)


5
간결함은 소중하지만 완전성은 더 소중합니다. nohup은 GNU coreutil이지만 bash 전용 답변 (또는 존재하지 않는 것에 대한 참고 사항)이 여기에 적합합니다. 그럼에도 불구하고 좋은 대답.
제한 속죄

23
nohupSIGHUP신호를 무시합니다 . 프로세스를 정상적으로 실행합니다. 데몬이 없습니다.
nemo

1
@nemo 프로세스가 분리되지 않았지만 init쉘이 종료되면 분리 (및 자식 ) 되는 것을 의미합니다 .
Noldorin

@Noldorin 예. 쉘이 종료 될 때 전송되는 SIGHUP을 무시하면 하위 프로세스가 실행되고 init로 재배치됩니다.
nemo

@nemo nohup은 표준 입력 / 출력을 침묵시킵니다. 완전히 분리하려면 disown으로 추적하십시오.
jiggunjer

60

당신이 사용하는 경우 bash, 시도 ; bash (1) 참조하십시오 .disown [jobspec]

시도 할 수있는 또 다른 방법은 at now입니다. 수퍼 유저가 아닌 경우 사용 권한 at이 제한 될 수 있습니다.


"disown"은 내부 bash 명령으로 보이지 않습니다 (내 컴퓨터에서는 사용할 수 없으며 bash를 사용합니다). Ben이 제안한 "nohup"은이 작업을 수행하는 훨씬 더 나은 (그리고 표준적인) 방법 일 수 있습니다.

1
"at"사용을 생각하지 않았습니다. 아이디어에 감사드립니다!
cadrian

1
at다른 사람에게 처형을 위임하기 위해, 나는 그것을 좋아합니다! +1
Ninsuo

1
참고로, 이것은 zsh또한 잘 작동 합니다.
코더

1
또한, disown함께 원하는 효과가 보이지 않는다 gnome-terminal- disown프로세스가 계속되면 터미널 종료 사망 에드. 왜 / 어떻게 알고 싶습니다.
Kyle Strand

38

이 답변을 읽음으로써 나는 발행 nohup <command> &이 충분 하다는 초기 인상을 받았다 . 그놈 터미널에서 zsh를 실행하면 종료시 nohup <command> &쉘이 자식 프로세스를 죽이는 것을 막지 못했습니다. nohup특히 비 대화식 쉘에서는 유용 하지만 자식 프로세스가 SIGHUP신호 처리기를 재설정하지 않은 경우에만이 동작을 보장합니다 .

필자의 경우 nohup행업 신호가 응용 프로그램에 도달하지 못했지만 자식 응용 프로그램 (이 경우 VMWare Player)이 SIGHUP처리기를 재설정하고있었습니다 . 결과적으로 터미널 에뮬레이터가 종료 될 때 하위 프로세스가 여전히 종료 될 수 있습니다. 이것은 프로세스가 셸의 작업 테이블에서 제거되었는지 확인하면 알 수 있습니다. 경우 nohup에 따라 셸 내장으로 재정의 된 경우에는 충분하지 않지만 경우에 따라 충분할 수 있습니다 ...


disown쉘이에 내장되고 bash, zsh그리고 ksh93,

<command> &
disown

또는

<command> &; disown

하나의 라이너를 선호한다면. 이는 작업 테이블에서 서브 프로세스를 제거 할 때 일반적으로 바람직한 효과가 있습니다. 따라서 실수로 자식 프로세스를 알리지 않고 터미널 에뮬레이터를 종료 할 수 있습니다. SIGHUP핸들러의 모양에 관계없이 자식 프로세스를 종료해서는 안됩니다.

해지 후에도 프로세스는 여전히 터미널 에뮬레이터의 하위 프로세스이지만 ( pstree이 동작을보고 싶다면 재생 ) 터미널 에뮬레이터가 종료 된 후 프로세스가 init 프로세스에 첨부 된 것을 볼 수 있습니다. 다시 말해서, 모든 것이 있어야하고, 아마도 당신이 원했던 것입니다.

쉘이 지원하지 않으면 어떻게해야합니까 disown? 나는 그렇게하는 것으로 전환하는 것을 강력히 권장하지만, 그 옵션이 없으면 몇 가지 선택이 있습니다.

  1. screen그리고 tmux이 문제를 해결할 수 있지만, 그들은 훨씬 더 무거운 무게 솔루션, 그리고 내가 같은 간단한 작업을 실행하는 것을 싫어한다. 일반적으로 원격 시스템에서 tty를 유지하려는 상황에 훨씬 적합합니다.
  2. 많은 사용자의 경우 쉘이 zsh 's와 같은 기능을 지원하는지 확인하는 것이 setopt nohup좋습니다. SIGHUP쉘이 종료 될 때 작업 테이블의 작업으로 전송되지 않도록 지정하는 데 사용할 수 있습니다 . 쉘을 끝내기 직전에 이것을 적용하거나 ~/.zshrc항상 원하는 것처럼 쉘 구성에 추가 할 수 있습니다.
  3. 작업 테이블을 편집하는 방법을 찾으십시오. tcsh또는 에서이 작업을 수행하는 방법을 찾지 못했습니다 csh. 다소 혼란 스럽습니다.
  4. 포크로 작은 C 프로그램을 작성하십시오 exec(). 이것은 매우 열악한 솔루션이지만 소스는 수십 줄로 구성되어야합니다. 그런 다음 명령을 명령 행 인수로 C 프로그램에 전달할 수 있으므로 작업 테이블에서 프로세스 특정 항목을 피할 수 있습니다.

29
  1. nohup $COMMAND &
  2. $COMMAND & disown
  3. setsid command

나는 오랫동안 2 번을 사용했지만 3 번도 잘 작동합니다. 또한 disownnohup플래그를 가지며로 -h모든 프로세스를 -a취소 할 수 있으며로 실행중인 모든 프로세스를 취소 할 수 있습니다 -ar.

침묵은에 의해 수행됩니다 $COMMAND &>/dev/null.

도움이 되었기를 바랍니다!


짧고 달다; 이 매우 유용한 요약에 감사드립니다!
쉘존


9

화면이 문제를 해결할 수 있다고 생각합니다


9

tcsh (및 다른 쉘에서도)에서 괄호를 사용하여 프로세스를 분리 할 수 ​​있습니다.

이것을 비교하십시오 :

> jobs # shows nothing
> firefox &
> jobs
[1]  + Running                       firefox

이에:

> jobs # shows nothing
> (firefox &)
> jobs # still shows nothing
>

그러면 작업 목록에서 파이어 폭스가 제거되지만 여전히 터미널에 연결됩니다. 'ssh'를 통해이 노드에 로그인 한 경우 로그 아웃을 시도해도 여전히 ssh 프로세스가 정지됩니다.


9

bash에 대한 가장 간단하고 정확한 답변 :

command & disown

터미널에서 프로세스를 분리 할 필요는 없지만 쉘에서 분리해야합니다.


7

예를 들어 하위 쉘을 통해 tty shell run 명령을 연결 해제하려면

(명령)&

종료시 터미널이 닫혔지만 프로세스는 여전히 활성 상태입니다.

확인-

(sleep 100) & exit

다른 터미널을여십시오

ps aux | grep sleep

프로세스는 여전히 살아 있습니다.


이것이 바로 내가 필요한 것입니다. 숭고한 텍스트에 대한 콘솔 바로 가기를 추가하려고 시도했는데 완벽하게 작동합니다. 다음은 끝났습니다. ( "/ opt / Sublime Text 2 / sublime_text"$ @) &
Ron E

5

작업의 배경과 포 그라운드는 아마도 모든 유닉스 시스템 관리자가 알아야 할 첫 번째 것 중 하나 일 것입니다.

bash로 수행하는 방법은 다음과 같습니다.

./script.sh
# suspend process
{ctrl-Z}
# background process
bg
# list all backgrounded jobs
jobs
# bring it back to foreground
fg

4

nohup 명령을 사용하여 명령을 실행할 수 있습니다. 이렇게하면 프로세스가 분리되고 출력이 지정된 파일로 경로 재 지정됩니다. 그러나 이것이 정확히 필요한지 확실하지 않습니다.


나는 exec를 사용하기 전에 nohup을 시도했다고 맹세 할 수는 있지만 다음과 같이 작동하므로 분명히 제대로 작동하지 않습니다. nohup gnome-terminal -e "vim $ @"&> / dev / null &

2

데몬을 사용해보십시오 -친숙한 패키지 관리자가 제공해야하며 터미널에서 자신을 분리하는 모든 방법을 종합적으로 관리하십시오.


2

bashrc / zshrc에 이것을 추가하십시오 :

detach() {
  "$@" 1>/dev/null 2>/dev/null &; disown
}

그런 다음 다음과 같이 사용하지 않는 명령을 실행할 수 있습니다.

detach gedit ~/.zshrc

1

내 .bashrc에는 정확하게 그 목적을 위해 다음과 같은 기능이 있습니다.

function run_disowned() {
    "$@" & disown
}

function dos() {
    # run_disowned and silenced

    run_disowned "$@" 1>/dev/null 2>/dev/null
}

명령을 접두사 dos로 실행하여 터미널에서 분리하십시오.

이 기능은 작업을 작성 bash하고 zsh.


1
이 답변이 본문과 함께 하나의 함수를 사용하기에 충분할 때이 함수가 다른 함수로 래핑 된 하나의 함수를 사용하는 이유에 대해서는 약간 혼란 스럽습니다 ( "$@" & disown) &> /dev/null. 또한 사용하지 않는 많은 의미가 1>하고 2>사용하고 있기 때문에, disown당신이 떠들썩한 파티를 사용하는 의미, 그리고 bash는 그냥 쉽게 할 수있는 &>표준 출력과 표준 에러 모두 리디렉션
세르지 Kolodyazhnyy

(1)이 방법을 읽는 것이 더 쉽다고 생각하고 (2) run_disowned내 도트 파일의 다른 위치에 기능이 필요하기 때문에 두 가지 기능이 있습니다. 물론 당신은 그 &>일 에 대해 옳 습니다.
mic_e

0

Mac OS X에서 자식 프로세스가 터미널에서 손상되지 않도록 nohup과 disown을 모두 사용해야한다는 것을 알았습니다.


0

다음 스크립트를 사용하여이 작업을 수행합니다. nohup명령이에서 완료되면 터미널로의 프로세스 인쇄를 중지하고로 분리 한 후 복귀 상태로 종료합니다 TIMEOUT.

#!/bin/bash

TIMEOUT=0.1

CMD=( "$@" )
#Could have some shortcuts here, e.g. replace "somefile.c" with "gedit somefile.c"

#use nohup to run the command, suppressing its output and allowing the terminal to be closed
#also send nohup's output to /dev/null, supressing nohup.out
#run nohup in the background so this script doesn't block
#print the command for debugging and to see bash variable expansion
printf "%q " "${CMD[@]}"
echo
nohup "${CMD[@]}" >/dev/null 2>&1 &
NOHUP_PID=$!

#kill this script after a short time, exiting with success status - command is still running
#this is needed as there is no timeout argument for `wait` below
MY_PID=$$
trap "exit 0" SIGINT SIGTERM
sleep $TIMEOUT && kill $MY_PID 2>/dev/null & #ignore "No such process" error if this exits normally

#if the command finishes before the above timeout, everything may be just fine or there could have been an error
wait $NOHUP_PID
NOHUP_STATUS=$?
#print an error if there was any. most commonly, there was a typo in the command
[ $NOHUP_STATUS != 0 ] && echo "Error: $CMD"
#return the exit status of nohup, whatever it was
exit $NOHUP_STATUS

사용 예 :

>>> run false
false
Error: false
>>> echo $?
1
>>> run true
true
>>> run sleep 10
sleep 10
>>>

0

sudo apt install ucommon-utils

pdetach command

당신은 간다 :)


-1

많은 답변이 nohup 사용을 제안했습니다 . 차라리 pm2 사용을 제안 합니다. nohup 보다 pm2 를 사용 하면 응용 프로그램을 유지하고 응용 프로그램에 대한 로그 파일을 유지 관리하는 등 많은 이점이 있습니다. 자세한 내용은 이것을 확인하십시오 .

pm2 를 설치하려면 npm 을 다운로드해야합니다 . 데비안 기반 시스템

sudo apt-get install npm

그리고 Redhat

sudo yum install npm

또는 이 지시를 따를 수 있습니다 . npm 을 설치 한 후 pm2 를 설치하는 데 사용하십시오.

npm install pm2@latest -g

완료되면 다음을 수행하여 응용 프로그램을 시작할 수 있습니다

$ pm2 start app.js              # Start, Daemonize and auto-restart application (Node)
$ pm2 start app.py              # Start, Daemonize and auto-restart application (Python)

프로세스 모니터링의 경우 다음 명령을 사용하십시오.

$ pm2 list                      # List all processes started with PM2
$ pm2 monit                     # Display memory and cpu usage of each app
$ pm2 show [app-name]           # Show all informations about application

앱 이름 또는 프로세스 ID를 사용하여 프로세스를 관리하거나 모든 프로세스를 함께 관리하십시오.

$ pm2 stop     <app_name|id|'all'|json_conf>
$ pm2 restart  <app_name|id|'all'|json_conf>
$ pm2 delete   <app_name|id|'all'|json_conf>

로그 파일은 다음에서 찾을 수 있습니다

$HOME/.pm2/logs #contain all applications logs

1
유닉스 프로세스를 제어하기 위해 NodeJS 응용 프로그램 (nohup과 같은 작고 강력한 명령 대)을 사용하면 ... 정말 과도하고 다소 정직한 것처럼 보입니다. 재시작 기능이 필요한 경우 monit을 사용합니다.
Sergio

@Sergio 더 이상 사용되지 않는 응용 프로그램을 사용하는 것이 좋습니다.
haccks

올해 (4 일 전)에 여러 차례 릴리스되었으므로 monit이 더 이상 사용되지 않는 응용 프로그램이라고 생각할 수있는 방법 / 이유는 없습니다. @see mmonit.com/monit/changes
세르지오

나는 nohup에 대해 이야기하고 있었다.
haccks 2016 년

1
nohup일반 표준 POSIX 명령이므로 사용되지 않습니다. @see unix.com/man-page/posix/1p/nohup
세르지오

-1

터미널 창을 유지하지 않고 단순히 명령 줄 응용 프로그램을 시작하는 것이 목표라면 alt-F2로 터미널을 시작한 후 응용 프로그램을 실행 해보십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.