대상 컴퓨터의 백그라운드에서 ssh가 명령을 실행하도록하기


304

이것은 쉘 스크립트에서 ssh를 어떻게 사용합니까? 에 대한 후속 질문입니다 . 질문. 해당 컴퓨터의 백그라운드에서 실행되는 원격 컴퓨터에서 명령을 실행하려면 ssh 명령을 어떻게 반환합니까? 명령 끝에 앰퍼샌드 (&)를 포함하려고하면 중단됩니다. 명령의 정확한 형태는 다음과 같습니다.

ssh user@target "cd /some/directory; program-to-execute &"

어떤 아이디어? 주목할 점은 대상 컴퓨터에 로그인하면 항상 텍스트 배너가 생성되고 SSH 키가 설정되어 있으므로 암호가 필요하지 않습니다.

답변:


315

나는 1 년 전에 작성한 프로그램 에서이 문제를 겪었습니다. 답이 다소 복잡하다는 것이 밝혀졌습니다. 당신은에 위키 피 디아 기사에에 설명 된대로 출력 경로 재뿐만 아니라 nohup을 사용해야합니다 nohup을 사용자의 편의를 위해 여기에 복사.

백그라운드 작업의 Nohuping은 예를 들어 SSH를 통해 로그인 할 때 유용합니다. 백그라운드 작업은 경쟁 조건으로 인해 셸이 로그 아웃에서 정지 될 수 있기 때문입니다 [2]. 이 문제는 세 개의 I / O 스트림을 모두 리디렉션하여 극복 할 수도 있습니다.

nohup myprogram > foo.out 2> foo.err < /dev/null &

1
해당 파일은 현재 디렉토리에 작성됩니다. 따라서 제한은 파티션에서 사용 가능한 공간의 양입니다. 물론으로 리디렉션 할 수도 있습니다 /dev/null.
Frank Kusters 2013

2
프롬프트 요청 완료 후 프로세스 배경에 대한 아이디어가 있습니까? (gpg --decrypt와 같이 암호 요청 완료)
isaaclw

nohup을 사용하여 백그라운드에서 임시 직원을 시작하려고했지만 작동하지 않습니다. : :(
Infant Dev

1
무슨 < /dev/null뜻 인지 설명해 주 시겠습니까? 감사.
Qian Chen

1
또한 nohup의 Wikipedia 기사에서 : "닫는 SSH 세션이 항상 종속 프로세스에 HUP 신호를 보내는 것은 아닙니다. 그 중에서도 의사 터미널의 할당 여부에 따라 다릅니다." 따라서 엄격히 nohup이 항상 필요한 것은 아니지만 그렇지 않은 것보다 장기적으로 더 좋습니다.
Jax

254

이것은 나를 위해 그것을하는 가장 깨끗한 방법이었습니다.

ssh -n -f user@host "sh -c 'cd /whereever; nohup ./whatever > /dev/null 2>&1 &'"

이 이후에 실행되는 유일한 것은 원격 시스템의 실제 명령입니다.


7
-n-f암시로 필요하지 않습니다-n
blissini

6
ssh -fssh 프로세스가 연결된 상태로 그대로 둡니다. / dev / null 솔루션을 사용하면 ssh의 연결을 빠르게 끊을 수 있으므로 바람직 할 수 있습니다.
Beni Cherniavsky-Paskin 2016 년

이 솔루션은 ssh를 통해 Syonology NAS로 명령을 보내는 데에도 사용됩니다
Stefan F

내 원격에 표시하려면 "ls -l"의 결과가 필요하지만이 명령은 수행하지 않습니다.
Siddharth

@Siddharth 그런 다음 / dev / null이 아닌 명명 된 파일로 리디렉션하십시오.
sherrellbc

29

fd의 리디렉션

&>/dev/nullstderr 및 stdout을 모두 / dev / null로 리디렉션하는 출력을 리디렉션 해야하며 >/dev/null 2>/dev/null또는 의 동의어입니다 >/dev/null 2>&1.

패 랭스 인

가장 좋은 방법은 sh -c '( ( command ) & )'command가 무엇이든 사용 하는 것입니다.

ssh askapache 'sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'

노 h 껍질

nohup을 직접 사용하여 쉘을 시작할 수도 있습니다.

ssh askapache 'nohup sh -c "( ( chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'

좋은 발사

또 다른 트릭은 nice를 사용하여 명령 / 쉘을 시작하는 것입니다.

ssh askapache 'nice -n 19 sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'

8
나는 이것이 당신의 아주 오래된 대답이라는 것을 알고 있지만, 괄호 방법이 왜 가장 좋은 방법인지 nohup, 왜 추가 가 더하고 , 왜 그리고 언제 사용할 것인지에 대한 의견을 추가 할 수 nice있습니까? 이 답변에 많은 도움이 될 것이라고 생각합니다.
Dr K

nohup을 사용하면 실행할 명령에 &를 추가 할 필요가 없습니다.
Cadoiz 2018 년

21

연결을 열 수 없거나 유지할 수없는 경우 설치 권한이있는 경우 screen을 사용할 수 있습니다 .

user@localhost $ screen -t remote-command
user@localhost $ ssh user@target # now inside of a screen session
user@remotehost $ cd /some/directory; program-to-execute &

스크린 세션을 분리하려면 : ctrl-a d

화면 세션을 나열하려면

screen -ls

세션을 다시 연결하려면

screen -d -r remote-command

화면은 각 세션 내에서 여러 개의 셸을 만들 수도 있습니다. tmux 에서도 비슷한 효과를 얻을 수 있습니다 .

user@localhost $ tmux
user@localhost $ ssh user@target # now inside of a tmux session
user@remotehost $ cd /some/directory; program-to-execute &

tmux 세션을 분리하려면 다음을 수행하십시오. ctrl-b d

화면 세션을 나열하려면

tmux list-sessions

세션을 다시 연결하려면

tmux attach <session number>

기본 tmux 제어 키 ' ctrl-b'는 사용하기가 다소 어렵지만 시도 할 수있는 tmux와 함께 제공되는 몇 가지 tmux 구성 예제가 있습니다.


3
screen이것을 어떻게 사용 합니까?
Quamis

18

잘라서 붙여 넣을 수있는 실제 예제를 보여주고 싶었습니다.

ssh REMOTE "sh -c \"(nohup sleep 30; touch nohup-exit) > /dev/null &\""

매우 도움이됩니다. 감사.
Michael Martinez

8

가장 빠르고 쉬운 방법은 'at'명령을 사용하는 것입니다.

ssh user @ target "현재 -f /home/foo.sh"


2
이것은 at파일뿐만 아니라 시간이 지난 후에 명령 행 인수를 허용하는 경우 훌륭한 일반 솔루션 입니다.
Tyler Collier

3
다음과 같이 <<<를 사용하여 파일을 시뮬레이션 할 수 있습니다. ssh user @ target "현재 -f <<< 'my_comnads'"
Nico

6

나는 당신이 원하는 것을 얻기 위해 두 가지 답변을 결합해야한다고 생각합니다. 세미콜론과 함께 nohup을 사용하고 모든 것을 따옴표로 묶으면 다음과 같은 결과가 나타납니다.

ssh user@target "cd /some/directory; nohup myprogram > foo.out 2> foo.err < /dev/null"

그것은 나를 위해 일하는 것 같습니다. nohup을 사용하면 실행할 명령에 &를 추가 할 필요가 없습니다. 또한 명령의 출력을 읽을 필요가 없으면 사용할 수 있습니다.

ssh user@target "cd /some/directory; nohup myprogram > /dev/null 2>&1"

모든 출력을 / dev / null로 리디렉션합니다.


5

이것은 때때로 나를 위해 일했다 :

ssh -x remoteServer "cd yourRemoteDir; ./yourRemoteScript.sh </dev/null >/dev/null 2>&1 & " 

2

당신은 이렇게 할 수 있습니다 ...

sudo /home/script.sh -opt1 > /tmp/script.out &

완벽하고 PuTTY SSH 세션과 함께 작동합니다. 종료해도 스크립트는 컴퓨터에서 계속됩니다. 감사합니다.
Satria

1

실제로 복잡한 원격 컴퓨터에서 명령을 실행해야 할 때마다 대상 컴퓨터의 스크립트에 명령을 넣고 ssh를 사용하여 해당 스크립트를 실행하고 싶습니다.

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

# simple_script.sh (located on remote server)

#!/bin/bash

cat /var/log/messages | grep <some value> | awk -F " " '{print $8}'

그런 다음 소스 머신에서이 명령을 실행합니다.

ssh user@ip "/path/to/simple_script.sh"

0

나는 똑같은 일을하려고했지만 Java에서 복잡성을 추가했습니다. 따라서 java를 실행하는 한 시스템에서 백그라운드에서 nohup을 사용하여 다른 시스템에서 스크립트를 실행하려고했습니다.

명령 행에서 다음과 같이 작동합니다. ( "-i keyFile"이 필요하지 않은 경우 호스트에 ssh 할 수 있습니다.)

ssh -i keyFile user@host bash -c "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\""

내 명령 행에는 "-c"뒤에 하나의 인수가 있으며 모두 따옴표로 묶여 있습니다. 그러나 다른 쪽 끝에서 작동하려면 여전히 따옴표가 필요하므로 그 안에 이스케이프 된 따옴표를 넣어야했습니다.

자바에서 다음과 같이 작동했습니다.

ProcessBuilder b = new ProcessBuilder("ssh", "-i", "keyFile", "bash", "-c",
 "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\"");
Process process = b.start();
// then read from process.getInputStream() and close it.

이 작업을 수행하는 데 약간의 시행 착오가 필요했지만 지금은 잘 작동하는 것 같습니다.


0

다음 과 같은 구문을 사용하여 원격 tmux 세션 을 갖는 것이 매우 편리해 보입니다 tmux new -d <shell cmd>.

ssh someone@elsewhere 'tmux new -d sleep 600'

elsewhere호스트에서 새 세션이 시작 되고 로컬 시스템의 ssh 명령이 거의 즉시 셸로 돌아갑니다. 그런 다음 원격 호스트 및 tmux attach해당 세션으로 ssh 할 수 있습니다 . 로컬 tmux 실행에 대해서는 아무것도 없으며 원격에만 있습니다!

또한 작업이 끝난 후에도 세션을 유지하려면 명령 뒤에 쉘 실행기를 추가하십시오. 그러나 따옴표로 묶는 것을 잊지 마십시오.

ssh someone@elsewhere 'tmux new -d "~/myscript.sh; bash"'

0
YOUR-COMMAND &> YOUR-LOG.log &    

명령을 실행하고 프로세스 ID를 지정해야합니다. 간단히 -f YOUR-LOG.log를 꼬리표에 적어 결과를 기록합니다. 언제든지 로그 아웃 할 수 있으며 프로세스가 계속 진행됩니다


0

nohup없이이 작업을 수행 할 수 있습니다.

ssh user@host 'myprogram >out.log 2>err.log &'

-2

나는 이것이 당신이 필요하다고 생각합니다. 처음에는 sshpass컴퓨터 에 설치 해야합니다. 그런 다음 자신의 스크립트를 작성할 수 있습니다.

while read pass port user ip; do
sshpass -p$pass ssh -p $port $user@$ip <<ENDSSH1
    COMMAND 1
    .
    .
    .
    COMMAND n
ENDSSH1
done <<____HERE
    PASS    PORT    USER    IP
      .      .       .       .
      .      .       .       .
      .      .       .       .
    PASS    PORT    USER    IP    
____HERE

-3

먼저이 절차를 따르십시오.

사용자 a로 A에 로그인하고 인증 키 쌍을 생성하십시오. 암호를 입력하지 마십시오 :

a@A:~> ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/a/.ssh/id_rsa): 
Created directory '/home/a/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/a/.ssh/id_rsa.
Your public key has been saved in /home/a/.ssh/id_rsa.pub.
The key fingerprint is:
3e:4f:05:79:3a:9f:96:7c:3b:ad:e9:58:37:bc:37:e4 a@A

이제 ssh를 사용하여 B에서 사용자 b로 ~ / .ssh 디렉토리를 작성하십시오 (디렉토리가 이미 존재할 수 있음).

a@A:~> ssh b@B mkdir -p .ssh
b@B's password: 

마지막으로 b의 새 공개 키를 b @ B : .ssh / authorized_keys에 추가하고 마지막으로 b의 비밀번호를 입력하십시오.

a@A:~> cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'
b@B's password: 

이제부터 비밀번호없이 A에서 B로 b로 B에 로그인 할 수 있습니다.

a@A:~> ssh b@B

암호를 입력하지 않아도 작동합니다

ssh b @ B "cd / some / directory; 프로그램 간 실행 &"


1
문제는 dagorym이 이미 암호를 요구하지 않도록 키를 설정했지만 여전히
멈췄습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.