Linux에서 SSH 클라이언트를 닫은 후 백그라운드 프로세스가 중지되지 않도록하는 방법


291

SSH (Putty)를 통해 Linux 컴퓨터에서 작업하고 있습니다. 밤 동안 프로세스를 실행 상태로 두어야하므로 백그라운드에서 프로세스를 시작하고 (명령 끝에 앰퍼샌드가있는) 프로세스를 stdout을 파일로 리디렉션하면됩니다.

놀랍게도 작동하지 않습니다. 퍼티 창을 닫으면 프로세스가 중지됩니다.

어떻게 그런 일이 발생하지 않도록 할 수 있습니까?

답변:


301

" nohup "프로그램을 확인하십시오 .


4
나중에 어떻게 중지합니까?
Derek Dahmer

9
로그인하고 "kill <pid>"를 수행하십시오. pid를 모른다면 "pidof"를 사용하십시오.
JesperE

32
nohup command > /dev/null 2>&1 &stdout 또는 stderr 출력 ( nohup.out파일 없음 ) 을 만들지 않고 백그라운드에서 실행할 수 있습니다.
KCD

입력을 제공해야하는 경우 어떻게합니까? 예를 들어, 백그라운드에서 실행해야하는 장기 실행 스크립트가 있지만 먼저 FTP 비밀번호를 요청합니다. nohup이 경우 도움이되지 않습니다. Ctrl+Z/ 로 바이올린을 칠 수있는 방법이 bg있습니까?
Sergey

1
나는 암호 문자 시퀀스를 암기하는 데 게으르고 나쁘기 때문에 @KCD의 말에 따라 이것을 쓰고 많이 사용했습니다.
Anomaly

167

GNU Screen을 사용하는 것이 좋습니다 . 모든 프로세스가 계속 실행되는 동안 서버와의 연결을 끊을 수 있습니다. 나는 그것이 존재하기 전에 내가 그것없이 어떻게 살았는지 모른다.


7
이것은 내가 사용 해본 최고의 소프트웨어 중 하나입니다. 진심으로. 나는 모든 곳에서 ssh로 BSD 상자에서 실행하고 있으며 단순히 화면에 다시 연결하고 모든 종류의 작업을 수행하는 모든 터미널을 가질 수 있습니다.
Adam Jaskiewicz 08.

1
나는 이것을 증명할 수있다. 화면은 훌륭한 응용 프로그램입니다. 다시 부착하는 기능은 놀랍고 잠재적으로 손실되는 작업을 많이 절약합니다.
willasaywhat

심지어 로컬 컴퓨터에서도 사용하고 여러 xterm을 동일한 화면 세션 (screen -x)에 연결합니다. 그렇게하면 화면 세션 내에서 많은 창을 열고 다양한 xterm을 창에서 창으로 자유롭게 전환 할 수 있습니다.
Adam Jaskiewicz 오전

17
백그라운드 앱에 다시 연결해야하는지 여부에 따라 다릅니다. 그렇다면 화면이 비행하는 유일한 방법입니다. 그러나 잊어 버린 경우 nohup은 더 좋지는 않더라도 청구서에 잘 맞습니다.
Dave Sherohman

1
화면 +1 또는 대안으로 tmux (화면보다이 기능이 마음에 듭니다) 또는 심지어 byobu는 screen 또는 tmux의 멋진 프론트 엔드입니다. 언제든지 screen을 입력하여 쉘이 언제든지 사용하고 나중에 리턴하도록하거나 "screen command"와 같은 screen을 사용하여 명령을 실행할 수 있습니다. 아주 길면 언제든지 표준 출력을 볼 수 있습니다.
gerlos

81

세션이 닫히면 프로세스는 포착하지 못하는 SIGHUP 신호를 수신합니다. 당신은 사용할 수 있습니다 nohup과정 또는 내장 명령 bash는 시작할 때 명령을 disown -h이를 방지 할 수있는 프로세스를 시작한 후를 :

> help disown
disown: disown [-h] [-ar] [jobspec ...]
     By default, removes each JOBSPEC argument from the table of active jobs.
    If the -h option is given, the job is not removed from the table, but is
    marked so that SIGHUP is not sent to the job if the shell receives a
    SIGHUP.  The -a option, when JOBSPEC is not supplied, means to remove all
    jobs from the job table; the -r option means to remove only running jobs.

4
여기서 장점은 이미 시작된 프로세스에 대해 작업을 제거한다는 것입니다.
Christian K.

1
'jobspec'이 pid를 의미합니까?
스튜어트

1
걱정하지 마세요.이 답변은 here 발견했습니다 stackoverflow.com/questions/625409/…
Stewart

42

데몬이? 노프? 화면? (tmux ftw, 화면이 잘못되었습니다 ;-)

처음부터 다른 모든 앱에서 수행 한 작업을 두 번 수행하십시오.

# ((exec sleep 30)&)
# grep PPid /proc/`pgrep sleep`/status
PPid:   1
# jobs
# disown
bash: disown: current: no such job

쾅! 완료 :-) 나는 모든 유형의 앱과 많은 오래된 컴퓨터 에서이 수많은 시간을 사용했습니다. 리디렉션과 결합하여 사용자와 프로세스간에 비공개 채널을 열지 않을 수 있습니다.

coproc.sh로 작성하십시오.

#!/bin/bash

IFS=

run_in_coproc () {
    echo "coproc[$1] -> main"
    read -r; echo $REPLY
}

# dynamic-coprocess-generator. nice.
_coproc () {
    local i o e n=${1//[^A-Za-z0-9_]}; shift
    exec {i}<> <(:) {o}<> >(:) {e}<> >(:)
. /dev/stdin <<COPROC "${@}"
    (("\$@")&) <&$i >&$o 2>&$e
    $n=( $o $i $e )
COPROC
}

# pi-rads-of-awesome?
for x in {0..5}; do
    _coproc COPROC$x run_in_coproc $x
    declare -p COPROC$x
done

for x in COPROC{0..5}; do
. /dev/stdin <<RUN
    read -r -u \${$x[0]}; echo \$REPLY
    echo "$x <- main" >&\${$x[1]}
    read -r -u \${$x[0]}; echo \$REPLY
RUN
done

그리고

# ./coproc.sh 
declare -a COPROC0='([0]="21" [1]="16" [2]="23")'
declare -a COPROC1='([0]="24" [1]="19" [2]="26")'
declare -a COPROC2='([0]="27" [1]="22" [2]="29")'
declare -a COPROC3='([0]="30" [1]="25" [2]="32")'
declare -a COPROC4='([0]="33" [1]="28" [2]="35")'
declare -a COPROC5='([0]="36" [1]="31" [2]="38")'
coproc[0] -> main
COPROC0 <- main
coproc[1] -> main
COPROC1 <- main
coproc[2] -> main
COPROC2 <- main
coproc[3] -> main
COPROC3 <- main
coproc[4] -> main
COPROC4 <- main
coproc[5] -> main
COPROC5 <- main

그리고 당신은 간다. <(:)은 프로세스 대체를 통해 익명 파이프를 열지 만 죽을 수도 있지만 핸들이 있기 때문에 파이프가 붙어 있습니다. 내가 일반적으로 할 sleep 1대신에 :그 약간 정확성 때문에, 그리고는 "파일 사용 중"오류를 얻을 것 - 진짜 명령이 실행 된 경우 발생하지 않습니다 (예 command true)

"heredoc 소싱":

. /dev/stdin <<EOF
[...]
EOF

이것은 busybox / etc (initramfs)를 포함하여 내가 시도한 모든 단일 쉘에서 작동합니다. 나는 전에 그것을 본 적이 없다. 나는 소스를 통해 인수를 받아 들일 수 있다는 것을 누가 알았 는가? 그러나 종종 그러한 것이 있다면 훨씬 관리하기 쉬운 형태의 평가로 사용됩니다.


2
왜 투표권이 떨어졌는가? 11 개의 다른 답변이 있다는 것을 고려하면 분명히 관련이 있습니다. 이 솔루션은 체계적이며, 예를 들어 무의미한 앱이 아닌 지난 30 년 동안 데몬 화하는 관용적이고 수용 가능한 방법입니다. nohup et al.
anthonyrisinger

7
당신의 대답이 아무리 좋더라도 때때로 누군가가 그것을 좋아하지 않고 공감할 것입니다. 너무 걱정하지 않는 것이 좋습니다.
Alex D

1
@ tbc0 ... tryssh myhost "((exec sleep 500)&) >/dev/null"
anthonyrisinger

1
@ Anthonyrisinger 좋아, 잘 작동합니다. 나는 이것이 더 깨끗하다고 ​​생각한다 : ssh myhost 'sleep 500 >&- 2>&- <&- &' TMTOWTDI;)
tbc0

1
대단하다. busybox에서 실제로 작동하는 유일한 솔루션입니다. 그것은 더 많은
공평을

34
nohup blah &

프로세스 이름을 blah로 대체하십시오!


2
리디렉션 표준 출력 및 표준 오류를 추가 할 수 있습니다.
David Nehme

9
nohup은 stdout 및 stderr을 nohup.out (또는 버전에 따라 nohup.out 및 nohup.err)으로 재 지정하므로 여러 명령을 실행하지 않는 한 필요하지 않습니다.
Chas. Owens

17

개인적으로 나는 '일괄 처리'명령을 좋아합니다.

$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D

이것은 배경에 넣은 다음 결과를 우편으로 보냅니다. 그것은 cron의 일부입니다.


11

다른 사람들이 언급했듯이 SSH 세션에서 연결을 끊을 수 있도록 백그라운드에서 프로세스를 실행하려면 백그라운드 프로세스가 제어 터미널 (SSH 세션이 사용하는 의사 tty)에서 자체적으로 연결 해제해야합니다.

Stevens의 "Advanced Network Program, Vol 1, 3rd Edn"또는 Rochkind의 "Advanced Unix Programming"과 같은 책에서 디먼 프로세스의 정보를 찾을 수 있습니다.

나는 최근 (지난 몇 년 동안) 스스로를 제대로 데몬하지 않은 재발견 프로그램을 다루어야했다. 나는 nohup과 비슷하지만 더 많은 컨트롤을 사용할 수있는 일반 데몬 화 프로그램을 만들어서 그 문제를 해결했습니다.

Usage: daemonize [-abchptxV][-d dir][-e err][-i in][-o out][-s sigs][-k fds][-m umask] -- command [args...]
  -V          print version and exit
  -a          output files in append mode (O_APPEND)
  -b          both output and error go to output file
  -c          create output files (O_CREAT)
  -d dir      change to given directory
  -e file     error file (standard error - /dev/null)
  -h          print help and exit
  -i file     input file (standard input - /dev/null)
  -k fd-list  keep file descriptors listed open
  -m umask    set umask (octal)
  -o file     output file (standard output - /dev/null)
  -s sig-list ignore signal numbers
  -t          truncate output files (O_TRUNC)
  -p          print daemon PID on original stdout
  -x          output files must be new (O_EXCL)

이중 대시는 GNU getopt () 함수를 사용하지 않는 시스템에서는 선택 사항입니다. Linux 등에서 필요하거나 환경에서 POSIXLY_CORRECT를 지정해야합니다. 이중 대시는 모든 곳에서 작동하므로 사용하는 것이 가장 좋습니다.

에 대한 소스를 원할 경우 여전히 저에게 연락 할 수 있습니다 (gmail dot com의 이름 점 성) daemonize.

그러나 코드는 지금 (마침내) 내에서 GitHub의에서 사용할 수 SOQ 파일로 (스택 오버플로 질문) 저장소 daemonize-1.10.tgz패키지 하위 디렉토리.


13
왜 소스를 github 또는 bitbucket에 넣지 않습니까?
Rob

5
왜 github에서 소스가 없으면 다운 보트가 필요합니까?
Jonathan Leffler

7
@JonathanLeffler IMHO는 독자의 시간을 낭비하지 않고 상업적으로도 이용할 수없는 프로그램의 모든 멋진 옵션을 나열합니다.
DepressionedDaniel

7

데비안 기반 시스템 (원격 컴퓨터)에 설치 :

sudo apt-get 설치 tmux

용법:

tmux

원하는 명령을 실행

세션 이름을 바꾸려면 :

Ctrl + B를 누른 다음 $

이름 설정

세션을 종료하려면

Ctrl + B , D

(이것은 tmux 세션을 떠납니다). 그런 다음 SSH에서 로그 아웃 할 수 있습니다.

다시 돌아와서 확인해야 할 경우 SSH를 시작하고 입력하십시오.

tmux 연결 session_name

tmux 세션으로 돌아갑니다.


이것은가는 길이다
kilgoretrout

6

대부분의 프로세스에서이 오래된 Linux 명령 행 트릭을 사용하여 의사 데모를 할 수 있습니다.

# ((mycommand &)&)

예를 들면 다음과 같습니다.

# ((sleep 30 &)&)
# exit

그런 다음 새 터미널 창을 시작하고 다음을 수행하십시오.

# ps aux | grep sleep

보여줄 것이다 sleep 30아직 실행 중임을 .

당신이 한 일은 자녀의 자녀로서 과정을 시작한 것입니다. nohup 일반적으로 프로세스를 종료시키는 명령은 손자에게 계단식으로 배열되지 않고 여전히 고아 프로세스로 남아 있습니다. .

나는이 "그것을 설정하고 그것을 잊지"접근, 처리 할 필요가 없습니다 선호 nohup, screenI / O를 리디렉션, TMUX을, 또는 그 물건의.


5

화면을 사용하여 프로세스를 루트로 실행하는 경우 권한 상승 공격의 가능성에주의하십시오. 자신의 계정이 어떻게 든 손상되면 전체 서버를 직접 인수 할 수 있습니다.

이 프로세스를 정기적으로 실행해야하고 서버에 대한 충분한 액세스 권한이있는 경우 cron을 사용하여 작업을 실행하는 것이 더 좋습니다. 또한 init.d (슈퍼 데몬)를 사용하여 백그라운드에서 프로세스를 시작할 수 있으며 완료 되 자마자 종료 될 수 있습니다.


5

nohup세부 정보를 파일에 기록하려는 경우 매우 좋습니다. 그러나 백그라운드로 갈 때 스크립트가 요청하면 암호를 제공 할 수 없습니다. 나는 당신이 시도해야한다고 생각합니다 screen. 예를 들어 CentOS에서 yum을 사용하여 Linux 배포판에 설치 yum install screen한 다음 셸 유형의 퍼티 또는 다른 소프트웨어를 통해 서버에 액세스 할 수있는 유틸리티 screen입니다. 퍼티 화면 [0]이 열립니다. 당신의 일을하십시오. 같은 퍼티 세션에서 더 많은 screen [1], screen [2] 등을 만들 수 있습니다.

알아야 할 기본 명령 :

화면을 시작하려면

화면


C reate 다음 화면

ctrl + a + c


로 이동하려면 n 개의 내선 화면 당신이 만든

ctrl + a + n


D 인 Etach

ctrl + a + d


작업하는 동안 퍼티를 닫으십시오. 다음에 퍼티 유형을 통해 로그인하면

화면 -r

화면에 다시 연결하면 화면에서 프로세스가 여전히 실행중인 것을 볼 수 있습니다. 그리고 화면 유형을 종료하려면 #exit를 입력하십시오.

자세한 내용은를 참조하십시오 man screen.


그것이 yum당신이 배포판을 알지 못할 때 그것이 올바른 도구 라고 가정하는 것은 좋지 않습니다. 어떤 배포판 screen을 설치할 수 있는지 명확히해야합니다 yum.
tymik

5

Nohup은 상위 프로세스가 종료 된 경우 클라이언트 프로세스가 종료되지 않도록합니다 (로그 아웃 할 때의 인수). 더 나은 여전히 ​​사용 :

nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG  " > /dev/null

Nohup은 사용자가 로그 아웃 할 때 SSH 세션과 해당 자식 프로세스가 종료되는 종료 과정에 영향을주지 않도록 프로세스를 시작합니다. 내가 준 명령은 나중에 응용 프로그램의 pid를 pid 파일에 저장하여 나중에 강제로 종료하고 로그 아웃 한 후에 프로세스를 실행할 수있는 방법을 제공합니다.




2

나는 또한 스크린 프로그램을 갈 것이다.

&, ctrl + z bg disown, nohup 등이 로그 오프 할 때 작업이 여전히 종료 될 것이라는 놀라운 놀라움을 줄 수 있다는 사실뿐만 아니라 (왜 그런지 모르겠지만, 그것은 나에게 일어 났으며 귀찮게하지 않았다) 그것으로 내가 화면을 사용하도록 전환 원인이 될 수 있지만, 나 또한 화면이이) 이중 포크 (fork) 등 anthonyrisinger 솔루션이 해결 것 같아요 주요 이상의 장점 그냥-접지 :

screen will background your process without losing interactive control to it

그리고 btw, 이것은 내가 처음에 묻지 않을 질문입니다 :) ... 나는 어떤 유닉스에서 무엇인가를 시작하는 처음부터 화면을 사용합니다 ... i (거의) 화면을 시작하지 않고 유닉스 / 리눅스 쉘에서 절대로 작동하지 않습니다 먼저 ... 그리고 나는 지금 멈춰야한다. 아니면 좋은 화면이 무엇인지, 나중에 무엇을 할 수 있는지에 대한 끝없는 프리젠 테이션을 시작할 것이다 ... 혼자서 찾아보십시오. 그만한 가치가있다.)


추신 : anthonyrisinger, 당신은 좋다, 나는 당신에게 그것을 제공하지만 ... 30 년? 나는 &, bg, nohup 또는 화면이 아직 거기에 없었을 때 해결책입니다. 당신의 지식에 감사하지만 그것을 사용하기에는 너무 복잡합니다 :)
THESorcerer

2
( 비공개 : Tmux 참조 ) 비록 이것이 나보다 훨씬 오래 되었지만 [1987], &(비동기 실행)은 1971 년 Thompson 쉘에 의해 유닉스 의 첫 번째 버전을 위해 도입 되었기 때문에 문자 그대로 "항상"이었다 " ;-) 나는 너무 보수적이었습니다. 실제로 41 년이 지났습니다.
anthonyrisinger

2

오픈 소스 libslack 패키지 의 데몬 명령 도 있습니다 .

daemon 꽤 구성 가능하며 자동 재시작, 로깅 또는 pidfile 처리와 같은 모든 지루한 데몬을 관리합니다.


2

이 문자열을 명령에 추가하십시오 :> &-2> &-<&-&. > &-는 가까운 stdout을 의미합니다. 2> &-는 가까운 stderr을 의미합니다. <&-는 가까운 stdin을 의미합니다. &는 백그라운드에서 실행됨을 의미합니다. 이것은 ssh를 통해 프로그래밍 방식으로 작업을 시작하기 위해 작동합니다.

$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$


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

이진 실행 파일은 pm2를 사용하여 실행할 수도 있습니다. Jason 파일을 변경해야합니다. 을 변경 "exec_interpreter" : "node"하기 위해 "exec_interpreter" : "none".합니다 (참조 속성 섹션 ).

#include <stdio.h>
#include <unistd.h>  //No standard C library
int main(void)
{
    printf("Hello World\n");
    sleep (100);
    printf("Hello World\n");

    return 0;
}

위의 코드 컴파일

gcc -o hello hello.c  

백그라운드에서 np2로 실행하십시오.

pm2 start ./hello

바이너리 실행 파일을 실행하는 데 사용할 수 있습니까?
GetFree

@무료로 얻을; 예. 할 수 있습니다.
haccks

예를 추가하십시오. 현재 답변은 스크립트 파일에만 적합한 것처럼 보입니다.
GetFree

@무료로 얻을; 예제를 추가했습니다. 문제가 있으면 알려주세요.
haccks

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