bash 스크립트를 사용하여 원격으로 여러 명령 실행

bash 스크립트를 사용하여 원격으로 여러 명령 실행

SSH를 통해 원격 서버에 로그인하고 tmp 폴더로 이동한 다음 rm 명령을 실행해야 합니다. 그런데 아래 스크립트를 실행하면 원격 서버로는 가는데 temp 폴더에는 가지 않고 rm 명령도 실행되지 않습니다.

#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS

답변1

코드의 유일한 실제 문제는 루프가 누락되어 구문 오류가 발생 do하고 done이를 루프 변수로 사용 하지만 설정되지 않은 i일부 변수를 연결하려고 한다는 것입니다 .server

cat그 외에도 따옴표 없이 명령 대체를 사용하고 있습니다 .일반적으로 말하면공백과 파일 이름 와일드카드 없이 문자열을 읽을 수 있을지 확신할 수 없다면 이는 좋지 않은 생각입니다(비록 대부분의 호스트 이름이 이 점에서 잘 작동하지만).

대부분의 경우 다음과 같이 입력 내용을 한 줄씩 읽는 것이 더 좋습니다.

while IFS= read -r remote; do
    ssh -n "$remote" 'rm -f /tmp/log52.log'
done <list

ssh -n여기서는 ssh표준 입력 스트림(파일에 연결됨) 읽기를 중지하는 데 사용하고 있습니다 list. 그렇지 않은 경우 -n나머지 ssh부분을 읽고 list루프는 한 번의 반복 동안만 실행됩니다.

또는 여기 문서에서 명령을 읽으려면 다음을 수행하십시오.

while IFS= read -r remote; do
    ssh -T "$remote" <<'END'
rm -f /tmp/log52.log
END
done <list

여기서는 ssh -T사용자 상호 작용이 필요한 작업을 수행하지 않기 때문에 필요하지 않은 의사 터미널 할당을 명시적으로 비활성화하는 방법을 사용합니다. ssh표준 입력 스트림에 데이터가 있다는 것을 알아차리고 원격 시스템에 상호 작용할 수 있는 터미널이 없다는 것을 경고하기 때문에 이렇게 합니다 . here 문서에서 표준 입력 스트림을 재할당 -n하기 때문에 여기서는 이것이 필요하지 않습니다 .sshssh

그러나 루프는 단일 명령으로 대체될 수 있습니다.

xargs -I {} ssh {} 'rm -f /tmp/log52.log' <list

... xargs유틸리티가 읽을 위치철사파일에서 list명령을 파일을 읽어 특정 파일을 삭제하기 위해 원격 시스템에 접속하는 동작을 수행하는 라인 {}으로 대체합니다. 삭제할 파일이 없으면 일반적으로 오류가 발생하지 않습니다.sshrm -f

예를 들어 일부 구현에서는 xargs유틸리티의 병렬 실행을 허용합니다 -P 4(최대 ssh4개의 동시 명령이 동시에 실행됨).

답변2

#! /bin/bash
for i in `cat list`
do
    echo $i
    echo "-------------------------"
    ssh $i "rm /tmp/log52.log"
done

파일 하나만 삭제해야 하는 경우에는 한 줄에 간단히 지정하면 됩니다. 또한 -f에 대한 추가 사항도 찾을 수 있습니다 rm.

답변3

이와 같이 SSH 세션의 표준 입력을 단순히 리디렉션할 수는 없습니다. 다음과 유사한 오류 메시지가 표시됩니다.

stdin이 터미널이 아니기 때문에 의사 터미널이 할당되지 않습니다.

의사 장치 할당을 강제하려면 ssh 옵션 -tt를 사용해야 합니다. 이 시도:

#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh -tt $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS

관련 정보