ssh 연결에서 완전히 분리 된 원격 명령 실행


48

나는이 컴퓨터를 가지고 localpcremoteserver.

localpc몇 가지 명령을 실행 해야 합니다 remoteserver. 필요한 작업 중 하나는 몇 시간 동안 실행되는 백업 스크립트를 시작하는 것입니다. 나는 localpc“화재” 명령을 받고 나서 처음에는 없었던 remoteserver것처럼 완전히 독립적으로 실행 하고 싶습니다 localpc.

이것이 내가 지금까지 한 일입니다.

remoteserver 포함 스크립트가 있습니다 :

/root/backup.sh

localpc 이것을 실행할 예정입니다.

ssh root@remoteserver 'nohup /root/backup.sh' &

내가 올바른 방법으로하고 있습니까? 더 좋은 방법이 있습니까? 이 방법으로 문제가 발생합니까?


stackoverflow.com/questions/19996089/…stackoverflow.com/questions/29142/… screen / tmux 등을 사용하지 않는이 문제에 대한 여러 가지 유용한 접근법을 제공합니다.
Paul

답변:


47

screen실제로 분리 된 명령을 사용 하려면 원격 호스트에서 사용해야 합니다.

ssh root@remoteserver screen -d -m ./script

나는이 아이디어를 좋아한다. 스크립트가 끝나면 화면이 계속 실행됩니다 ... 다음에 스크립트를 실행하려고 할 때 어떻게 든 다시 연결해야합니까?
LVLAaron

@AaronJAnderson : 아니요, 명령이 쉘이 아닌 경우 종료 될 때 해당 화면 세션도 종료됩니다.
enzotib

52

닫히지 만 정확히는 아닙니다.

모든 터미널과 독립적으로

ssh root@remoteserver '/root/backup.sh </dev/null >/var/log/root-backup.log 2>&1 &'

일부 원격 프로세스에서 소켓이 열려있는 한 ssh 세션이 닫히지 않기 때문에 ssh 소켓에 연결된 모든 파일 디스크립터를 닫아야합니다. 스크립트 출력에 관심이없는 경우 (아마도 스크립트 자체가 로그 파일에 쓰는 작업을 처리하기 때문에)이를 리디렉션합니다 /dev/null(그러나 스크립트를 시작할 수없는 등의 오류는 숨겨집니다).

사용 nohup은 여기서 아무런 효과가 없습니다. nohup프로그램의 제어 터미널이 사라지면 HUP 신호를 수신하지 않도록 프로그램을 정렬하지만 여기에는 맨 처음에 터미널이 없으므로 프로세스에서 SIGHUP을 파란색으로 보내지 않습니다. 또한 nohup표준 출력 및 표준 오류 (표준 입력은 아님)를 파일로 리디렉션하지만 터미널에 연결되어있는 경우에만 다시 연결합니다.

터미널에서 분리

 aaron@localpc$ ssh root@remoteserver
 root@remoteserver# nohup /root/backup.sh </dev/null &
 nohup: appending output to `nohup.out'
 [1] 12345
 root@remoteserver# exit
 aaron@localpc$ 

터미널이 사라질 때 SIGHUP을nohup 받지 않도록 제어 터미널에서 스크립트를 분리하는 데 사용하십시오 . 또한 스크립트의 표준 출력 및 표준 오류를 터미널에 연결된 경우 호출 된 파일로 리디렉션합니다 . 표준 입력을 직접 관리해야합니다.nohupnohup.out

원격 터미널 유지

원격 터미널에서 명령을 계속 실행하고 SSH 세션에 연결하지 않으려면 Screen 또는 Tmux 와 같은 터미널 멀티플렉서에서 명령을 실행하십시오 .

ssh root@remoteserver 'screen -S backup -d -m /root/backup.sh'

나중에 screen -S backup -rd해당 머신에서 루트 로 호출하여 스크립트가 실행중인 터미널에 다시 연결할 수 있습니다 .

하나의 원격 명령 자동화

약간 더 나은 보안을 위해 직접 원격 루트 로그인을 너무 넓게 열지 마십시오. 특수 목적 키 페어를 만들고에 강제 명령을 내 /root/.ssh/authorized_keys립니다. 공개 키 파일의 내용은 AAAA…== wibble@example.com; command="…"키가이 특정 명령을 실행하는 데만 사용될 수 있음을 지정하는 옵션을 포함하여 쉼표로 구분 된 옵션 목록을 추가하십시오 . 옵션과 키를 모두 한 줄로 유지하십시오.

command="/root/backup.sh </dev/null >/dev/null 2>/dev/null &",no-port-forwarding,no-agent-forwarding,no-x11-forwarding,no-pty,no-user-rc AAAA…== wibble@example.com

나열된 첫 번째 명령을 시도했습니다. 명령을 실행 한 상자에는 배경이 없습니다. 커서가 저기에 앉아 완료를 기다립니다. 아마도 버그일까요?
LVLAaron

원격 시스템에서 stdin을 / dev / null로 경로 재지 정해야 할 수도 있습니다. ssh가 종료되지 않는 이유가 여기에 있습니다.
KeithB

-f로컬 쪽에서 ssh를 '배경'(즉, 종료, 연결 닫기)으로 가져 오는 옵션을 추가합니다 . 이것은와 함께 작동합니다 &. nohup이 경우 선택 사항이지만 setsid대신 사용하는 것이 좋습니다.
Alexios

@KeithB stdin 리디렉션은 그 일부이지만 stdout 및 stderr도 리디렉션해야합니다. nohup은 터미널이 아니기 때문에 여기에서 수행하지 않으며 실제로 nohup은 유용하지 않습니다.
Gilles 'SO- 악마 그만해'

1
@erikbwork 나는 그 것들에 대해 전혀 단서가 없지만 토론과 의견을 따르면 : Gilles는 그의 명령에 -t 옵션을 사용하지 않으므로 클라이언트와 서버에서 의사 터미널이 설정되지 않습니다. 측면. 따라서 HUP가 전송되지 않습니다.
Binarus

12

SSH와 같은 원격 로그인에서 원격 명령을 실행하는 표준 레시피는 다음과 같습니다.

nohup command </dev/null >command.log 2>&1 &

경우 command파일 자체에 로깅을 담당 쉘 스크립트입니다, 당신은 변경 될 수 있습니다 command.log/dev/null. 일단 시작하면 즉시 로그 오프하십시오.

그 라인에 모든 것이 필요합니다.

nohup 로그인 세션의 연결이 끊어지면 프로세스를 방해하지 않도록 쉘에 지시합니다.

</dev/null 입력을 기다리지 말라고한다

>command.log 이 명명 된 로그 파일에 메시지를 보내도록 지시합니다.

2>&1stderr 메시지를 동일한 로그 파일로 보내도록 지시합니다. 어떤 경우에는 두 개의 파일, 두 번째 파일은 오류 메시지를 수집하고 첫 번째 파일은 일반 활동 메시지를 수집하는 것이 좋습니다. 모든 것이 올바르게 작동하는지 쉽게 확인할 수 있습니다.

& 이 프로세스를 분리하고 백그라운드에서 데몬 프로세스로 실행하도록 지시합니다.


10

이 스레드는 매우 도움이되었지만 내 솔루션은 약간 달라야했습니다.

화면 솔루션이 필요하지 않은 화면 프로세스를 남겨두고 있기 때문에 화면 솔루션이 마음에 들지 않습니다. 리디렉션 및 nohups는 다음과 같이 사용되었습니다.

ssh root@remoteserver '/root/backup.sh </dev/null >/var/log/root-backup.log 2>&1 &'

ssh 명령과 함께 사용할 때 나를 위해 작동하지 않았습니다.

실제 스크립트를 실행하는 원격 컴퓨터에서 래퍼 스크립트를 만들었습니다. 랩퍼 스크립트는 경로 재 지정 및 nohup을 설정합니다. 이 같은:

backupwrapper.sh:
nohup backup.sh > /dev/null 2>&1 &

그런 다음 클라이언트 컴퓨터에서 다음을 실행합니다 (리디렉션 없음).

# ssh remotemachine "backupwrapper.sh"
#

ssh 명령이 즉시 리턴되고 연결이 종료되고 스크립트는 계속 실행됩니다.


6

으로 닐스는 말한다 ,이 루트는 ssh를 통해 로그인 할 수 있도록 보안 위험이 있습니다. 그리고 로그없이 머신에서 실질적인 작업을 실행하지 않는 것이 좋습니다. 문제가 발생하면 문제 해결 메시지가 표시되기를 바랍니다. 그 방법을 보여주는 다른 답변이 있습니다. 그러나 여기에 내가 요청한 것을 달성하는 것이 좋습니다. 그것은 모두 sh (1)에 내장되어 있습니다. GNU 화면이 필요하지 않습니다 (영리한 솔루션이라고 생각하지만). 이 문자열을 명령에 추가하십시오 >&- 2>&- <&- &. >&-가까운 stdout을 의미합니다. 2>&-가까운 stderr을 의미합니다. <&-가까운 stdin을 의미합니다. &백그라운드에서 실행하는 것, 예.

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

0

에 원격 명령을 백그라운드로 지정해야합니다 remoteserver. 당신이 그것을하는 방법에 ssh 명령을 배경으로합니다 localpc.

그 외에도 root-ssh를 허용하는 것은 나쁜 생각입니다.

설정 remoteserver: sudoers 라인은 /root/backup.sh사용자에 의해 루트로 실행 됩니다 backup.

"좋은"암호없이 해당 사용자를 만들 수 있습니다.

공개 키와 함께 (스크립트를 트리거하는 사람) sudo /root/backup.sh &명령을 명령 으로 명령에 넣습니다 .~backup/.ssh/authorized_keyslocalpc


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