이더넷 스위치를 통해 여러 대의 컴퓨터가 네트워크로 그룹화되어 있습니다. 이들 모두는 Fedora 서버를 실행하며 인터넷에 연결되어 있습니다.
나에게 필요한 것은 다음과 같은 스크립트입니다.
- 목록의 모든 노드에 연결
- 명령 또는 명령 패키지 보내기(예: 전체 업데이트 또는 특정 패키지 설치)
- 연결을 닫지만 대상 시스템에서 명령 실행을 유지합니다.
현재 스크립트는 다음과 같습니다.
#!/bin/bash
targets_username='username'
targets_password='password'
targets_IPs=( 192.168.1.100 192.168.1.101 192.168.1.102 )
SCRIPT1='dnf update -y'
SCRIPT2='dnf update -y && poweroff'
for IP in ${targets_IPs[@]}; do
export SSHPASS=$targets_password
script="nohup sh -c \"( ( $SCRIPT1 & > /dev/null) &)\""
echo $IP
echo $script
sshpass -e ssh -o StrictHostKeyChecking=no -l $targets_username@$IP $script
done
문제는 다음과 같습니다
- 연결이 닫히면 명령 실행이 중지됩니다.
- 예를 들어, 명령에 추가 명령이 포함되어 있거나 호스트 컴퓨터로 전달되는 경우
reboot
해당poweroff
호스트 컴퓨터에서 스크립트가 시작됩니다.
이 문제를 어떻게 해결하나요?
답변1
이러한 유형의 통화는 올바른 위치에서 사물을 평가하고 있는지 확인해야 하기 때문에 항상 까다롭습니다. 즉. 올바른 수의 백슬래시를 추가하십시오.
당신이 그렇게한다면
script="sh -c \"nohup sh -c '$SCRIPT1' > /dev/null 2>&1 & \""
sshpass -e ssh -n -o StrictHostKeyChecking=no -l $targets_username $IP "$script"
원하는 대로 작동해야 합니다( -n
stdin을 닫아 두십시오). time
SSH 연결 앞에 sshpass 명령을 추가하거나 실행하고 netstat
열린 $SCRIPT1
연결을 확인하여 SSH 연결이 실제로 닫혔는지 확인할 수 있습니다 .
stdin, stdout 및 stderr이 모두 닫혀 있는지 확인해야 합니다. 그렇지 않으면 ssh
프로세스가 백그라운드로 전환되더라도 닫힐 때까지 기다려야 합니다.
위의 방법이 작동하지 않으면 명령줄 인수에 대한 추가 평가가 수행될 수 있습니다 sshpass
. 또한 작은따옴표를 사용하면 원격 측까지 $SCRIPT1
내부 변수(예: 쉘 변수)의 확장이 지연됩니다 .$SCRIPT1
이제 이 접근 방식을 사용하여 작업을 수행할 수 있더라도 Ansible(https://docs.ansible.com/ansible/latest/index.html). 백그라운드 접근 방식을 사용하면 명령이 성공했는지 또는 실행이 완료되었는지 수동으로(또는 다른 개발된 도구를 사용하여) 확인해야 합니다.