대상 시스템에서 백그라운드에서 명령을 실행하도록 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"'
하지 않고 tty를 리다이렉트합니다.
stdout/stderr
작동하다,nohup
는 필요 없습니다.ssh user@host 'background command &>/dev/null &'
「 」를 사용하고
-t
명령어와 를 실행하는데 입니다.ttty 명령어는 background 명령어입니다.background 명령어는 .ssh -t user@host 'bash -c "interactive command; nohup backgroud command &>/dev/null &"'
도 있다
background command
실제로 시작되지 않습니다.여기에 인종이 있습니다.bash
nohup
로서 세션 리더로서bash
로 끝나다HUP
송신되는nohup
★★★★★★ 。nohup
HUP
★★★★★★ 。
if
1
에 완성되다2
, . . . . . . . .nohup
되고,background command
기다릴 필요가nohup
background 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 명령어를 큰따옴표로 묶는 방법도 보여 줍니다.템플릿이 내부에서 호출될 경우 다음과 같이 표시됩니다.PowerShell
script(이중괄호 내에서만 변수를 보간할 수 있으며 작은 따옴표로 둘러싸인 경우 변수 확장은 무시됩니다):
ssh user@server "sh -c `"($cmd) &>/dev/null </dev/null &`""
내부 이중 따옴표는 백슬래시 대신 백틱으로 이스케이프됩니다.이렇게 하면$cmd
에 의해 구성되다PowerShell
스크립트, 예를 들어 배포 스크립트 및 자동화 등에 사용됩니다. $cmd
여러 줄을 포함할 수도 있습니다.heredoc
unix로 구성되는 경우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
'programing' 카테고리의 다른 글
무제한 Bash 이력 (0) | 2023.04.08 |
---|---|
파이프 출력 및 캡처 종료 상태(Bash) (0) | 2023.04.08 |
한 셸 스크립트에서 다른 셸 스크립트로 모든 변수를 전달하시겠습니까? (0) | 2023.04.08 |
Bash 스크립트를 사용하여 사용자 계정과 비밀번호를 자동으로 추가하는 방법은 무엇입니까? (0) | 2023.04.08 |
.Net 데이터 구조:Array List, List, HashTable, Dictionary, Sorted List, Sorted Dictionary -- 속도, 메모리, 사용 시기 (0) | 2023.04.08 |