programing

대상 시스템에서 백그라운드에서 명령을 실행하도록 ssh를 가져오는 중

goodcopy 2023. 4. 8. 11:24
반응형

대상 시스템에서 백그라운드에서 명령을 실행하도록 ssh를 가져오는 중

이것은 셸 스크립트에서 ssh를 사용하는 방법에 대한 후속 질문입니다.질문.해당 머신 상에서 백그라운드에서 실행되는 리모트머신에서 명령을 실행하는 경우 ssh 명령어를 반환하려면 어떻게 해야 합니까?명령어 끝에 앰퍼샌드(&)를 포함하려고 하면 정지합니다.명령어의 정확한 형식은 다음과 같습니다.

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

좋은 생각 있어요?주의할 점은 타깃머신에 로그인하면 항상 텍스트배너가 생성되고 SSH 키가 설정되어 있기 때문에 패스워드가 필요 없습니다.

1년 전에 작성한 프로그램에서 이 문제가 있었습니다.해답은 꽤 복잡합니다.wikipedia artcle on nohup에서 설명한 바와 같이 nohup과 출력 리다이렉션을 사용하여 편리합니다.

예를 들어 백그라운드 작업은 경합 조건으로 인해 로그아웃 시 셸이 중단될 수 있으므로 SSH를 통해 로그인할 때 유용합니다 [2].이 문제는 다음 3개의 I/O스트림을 모두 리다이렉트하여 해결할 수도 있습니다.

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

지금까지 가장 깔끔한 방법으로 해왔습니다.-

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

그 후에 실행되는 것은 리모트머신에서의 실제 명령어뿐입니다.

fd의 리다이렉트

&>/dev/null및 /dev stderr stdout의 입니다.>/dev/null 2>/dev/null ★★★★★★★★★★★★★★★★★」>/dev/null 2>&1.

패런치

은 '우리'를 사용하는 입니다.sh -c '( ( command ) & )'명령하다

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

노업셸

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 ) & )"'

연결을 열어두지 않거나 열 수 없는 경우 설치 권한이 있는 경우 화면을 사용할 수 있습니다.

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 &

화면 세션을 분리하려면:

화면 세션을 나열하려면:

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 세션을 분리하려면:

화면 세션을 나열하려면:

tmux list-sessions

세션을 재접속하려면:

tmux attach <session number>

기본 tmux 컨트롤 키인 ''ctrl-b는 사용하기 어렵지만 tmux와 함께 제공되는 몇 가지 tmux 구성 예가 있습니다.

컷앤페이스트할 수 있는 작업 예를 보여드리고 싶습니다.

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

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

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

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

ssh user@target "at now -f /home/foo.sh"

원하는 것을 얻으려면 이 대답들 중 몇 가지를 조합해야 할 것 같아요.세미콜론과 함께 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/module로 리다이렉트합니다.

이것은 나에게 몇 번인가 효과가 있었다.

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

이렇게 하면...

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

리모트 tmux 세션을 사용하는 것은 매우 편리해 보였습니다.tmux new -d <shell cmd>다음과 같이 합니다.

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

새 됩니다.elsewhere「호스트」 「ssh」 「ssh」 「ssh」 「ssh」 「ssh」 「ssh」 「ssh」 「ssh」 「ssh」 「ssh」」 「ssh」 「ssh」 「ssh」 「ssh」 후 하여 "ssh"를 사용할 수 .tmux attach을 사용하다로컬 tmux 실행에는 아무런 문제가 없으며 원격만 실행됩니다.

또한 작업이 완료된 후에도 세션을 지속하려면 명령어 뒤에 셸 런처를 추가하기만 하면 되지만 따옴표로 묶는 것을 잊지 마십시오.

ssh someone@elsewhere 'tmux new -d "~/myscript.sh; bash"'
  1. 하지 않고 tty를 리다이렉트합니다.stdout/stderr작동하다,nohup는 필요 없습니다.

    ssh user@host 'background command &>/dev/null &'

  2. 「 」를 사용하고 -t명령어와 를 실행하는데 입니다.ttty 명령어는 background 명령어입니다.background 명령어는 .

    ssh -t user@host 'bash -c "interactive command; nohup backgroud command &>/dev/null &"'

    도 있다background command실제로 시작되지 않습니다.여기에 인종이 있습니다.

    1. bashnohup로서 세션 리더로서bash로 끝나다HUP 송신되는 nohup★★★★★★ 。
    2. nohupHUP★★★★★★ 。

    if1에 완성되다2 , . . . . . . . .nohup되고, background command기다릴 필요가 nohupbackground command .sleep:

    ssh -t user@host 'bash -c "interactive command; nohup backgroud command &>/dev/null & sleep 1"'

몇 년 전에 질문하고 대답했는데, 그 이후로 openssh 동작이 바뀌었는지 모르겠습니다. ★★★★★★★★★★★★★★★★★★★★★★★:OpenSSH_8.6p1, OpenSSL 1.1.1g FIPS 21 Apr 2020

실제로 복잡한 리모트머신에서 명령어를 실행해야 할 때는 항상 타깃머신의 스크립트에 명령어를 삽입하고 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"

저도 똑같이 하려고 했는데 자바에서 하려고 했던 복잡함이 더해져요.java를 실행하고 있는 머신에서는 백그라운드에서 (nohup을 사용하여) 스크립트를 실행하려고 했습니다.

명령줄에서 다음과 같이 동작합니다(-i key File이 호스트에 ssh할 필요가 없는 경우 "-i key File"이 필요하지 않을 수 있습니다).

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

명령줄에서는 "-c" 뒤에 하나의 인수가 있으며 모두 따옴표로 둘러싸여 있습니다.하지만 반대쪽에서 작동하기 위해서는 여전히 견적이 필요하기 때문에 나는 그 안에 이스케이프된 견적을 넣어야 했다.

Java에서는 다음과 같이 동작합니다.

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.

조금 시행착오가 있었지만, 지금은 정상적으로 동작하고 있는 것 같습니다.

YOUR-COMMAND &> YOUR-LOG.log &    

그러면 명령어가 실행되어 프로세스 ID가 할당됩니다.이 ID는 단순히 -f YOUR-LOG.log에 따라 작성되는 결과를 확인할 수 있습니다.언제든지 로그아웃할 수 있으며 프로세스는 계속 진행됩니다.

zsh를 사용하는 경우program-to-execute &!는 백그라운드와 디어넥트프로세스 모두에 대한 zsh 고유의 단축키입니다.이것에 의해, 셸을 종료하는 것으로, 셸은 동작한 채로 남습니다.

@cmcginty의 후속 작업 예에서는 outer 명령어를 큰따옴표로 묶는 방법도 보여 줍니다.템플릿이 내부에서 호출될 경우 다음과 같이 표시됩니다.PowerShellscript(이중괄호 내에서만 변수를 보간할 수 있으며 작은 따옴표로 둘러싸인 경우 변수 확장은 무시됩니다):

ssh user@server "sh -c `"($cmd) &>/dev/null </dev/null &`""

내부 이중 따옴표는 백슬래시 대신 백틱으로 이스케이프됩니다.이렇게 하면$cmd에 의해 구성되다PowerShell스크립트, 예를 들어 배포 스크립트 및 자동화 등에 사용됩니다. $cmd여러 줄을 포함할 수도 있습니다.heredocunix로 구성되는 경우LF.

우선, 다음의 순서에 따릅니다.

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: 

마지막으로 a의 새 공용 키를 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에 로그인 할 수 있습니다.

a@A:~> ssh b@B

패스워드를 입력하지 않아도 동작합니다.

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

이게 당신이 필요한 거라고 생각해요.처음에 설치하셔야 합니다.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

언급URL : https://stackoverflow.com/questions/29142/getting-ssh-to-execute-a-command-in-the-background-on-target-machine

반응형